我想在android原生代码中的flutter中使用pusher sdk,因为它的库在flutter中尚未完全受支持,但是当我发送第一个消息时,它成功收到了下一条消息,使应用程序崩溃并带有Reply已提交错误,她在此行结果上.success(txt);
公共类MainActivity扩展了FlutterActivity { 私有静态最终字符串CHANNEL =“ demo.gawkat.com/info”;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("getMessage")) {
Pusher pusher = new Pusher("faa685e4bb3003eb825c");
pusher.connect();
Channel channel = pusher.subscribe("messages");
channel.bind("new_message", (channelName, eventName, data) -> runOnUiThread(() -> {
Gson gson = new Gson();
Message message = gson.fromJson(data, Message.class);
String txt = message.text;
result.success(txt);
}));
}
});
}
}
颤振代码 未来_getMessage()异步{
String value;
try {
value = await platform.invokeMethod('getMessage');
} catch (e) {
print(e);
}
return value;
} 错误是 致命异常:主要 流程:com.example.flutter_app,PID:6296 java.lang.IllegalStateException:答复已提交 在io.flutter.view.FlutterNativeView $ PlatformMessageHandlerImpl $ 1.reply(FlutterNativeView.java:197) 在io.flutter.plugin.common.MethodChannel $ IncomingMethodCallHandler $ 1.success(MethodChannel.java:204) 在com.example.flutter_app.MainActivity.lambda $ null $ 0(MainActivity.java:40) 在com.example.flutter_app .- $$ Lambda $ MainActivity $ axbDTe2B0rhavWD22s4E8-fuCaQ.run(未知来源:4) 在android.os.Handler.handleCallback(Handler.java:789) 在android.os.Handler.dispatchMessage(Handler.java:98) 在android.os.Looper.loop(Looper.java:164) 在android.app.ActivityThread.main(ActivityThread.java:6541) 在java.lang.reflect.Method.invoke(本机方法) 在com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767
答案 0 :(得分:1)
我认为这是在Flutter升级> 1.5.4.hotfix之后发生的。
无论如何,是的,有解决方案(Refer this github issue)
在您的Activity
下方onCreate()
上添加此类:
private static class MethodResultWrapper implements MethodChannel.Result {
private MethodChannel.Result methodResult;
private Handler handler;
MethodResultWrapper(MethodChannel.Result result) {
methodResult = result;
handler = new Handler(Looper.getMainLooper());
}
@Override
public void success(final Object result) {
handler.post(
new Runnable() {
@Override
public void run() {
methodResult.success(result);
}
});
}
@Override
public void error(
final String errorCode, final String errorMessage, final Object errorDetails) {
handler.post(
new Runnable() {
@Override
public void run() {
methodResult.error(errorCode, errorMessage, errorDetails);
}
});
}
@Override
public void notImplemented() {
handler.post(
new Runnable() {
@Override
public void run() {
methodResult.notImplemented();
}
});
}
}
然后,不要使用MethodChannel
结果作为setMethodCallHandler
参数回调将名称添加为rawResult
,然后在该回调中添加以下行:
MethodChannel.Result result = new MethodResultWrapper(rawResult);
如下:
//......
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
(call, rawResult) -> {
MethodChannel.Result result = new MethodResultWrapper(rawResult);
//.....
答案 1 :(得分:1)
我使用标志来解决这个问题。 只需确保同时调用相同通道的方法即可。 然后问题似乎出现了。
如果需要同时调用两个方法而没有任何问题,请在 2 个不同的通道中定义这两个方法
var resultMap = Map<String, MethodChannel.Result> = HashMap()
new MethodChannel(getFlutterView(), CHANNEL_1).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("method1")) {
// implement method 1
}
});
new MethodChannel(getFlutterView(), CHANNEL_2).setMethodCallHandler((methodCall, result) -> {
final Map<String, Object> arguments = methodCall.arguments();
if (methodCall.method.equals("method2")) {
resultMap = resultMap + mapOf(CHANNEL_2 to MethodResultWrapper(result) // use this later to return result
// implement method2
result.success(true) // or whatever value
}
});
这减少了“回复已经提交”错误的机会。
如果您使用 MethodResultWrapper 作为 @Blasanka 答案,请在 result.success 之前使用标志
调用方法时设置标志为真
val methodCheckFlag: Boolean = true
然后什么时候需要返回结果
if(methodCheckFlag) {
methodCheckFlag = false;
methodWrapperResult?.success(true) // or what ever value to return
}
或使用保存的 MethodResultWrapper 作为
if(methodCheckFlag) {
methodCheckFlag = false;
resultMap[CHANNEL_2]?.success(true) // or what ever value to return
}