4

我正在创建 Flutter 插件。我将回调从 Android 发送到 Flutter 的渠道很少。情况是我正在监听一些在 OTHER 线程而不是主 UI 线程中触发的事件。

在最近的 Flutter 更新之后,我开始收到这样的错误

E/AndroidRuntime( 9400): FATAL EXCEPTION:  STARTING
E/AndroidRuntime( 9400): Process: com.northernbitcoin.coinyacapp, PID: 9400
E/AndroidRuntime( 9400): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread:  STARTING
E/AndroidRuntime( 9400):    at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:794)
E/AndroidRuntime( 9400):    at io.flutter.embedding.engine.FlutterJNI.dispatchPlatformMessage(FlutterJNI.java:684)
E/AndroidRuntime( 9400):    at io.flutter.embedding.engine.dart.DartMessenger.send(DartMessenger.java:80)
E/AndroidRuntime( 9400):    at io.flutter.embedding.engine.dart.DartExecutor.send(DartExecutor.java:174)
E/AndroidRuntime( 9400):    at io.flutter.view.FlutterNativeView.send(FlutterNativeView.java:144)
E/AndroidRuntime( 9400):    at io.flutter.plugin.common.EventChannel$IncomingStreamRequestHandler$EventSinkImplementation.success(EventChannel.java:226)
...

我找到的唯一信息在这里 https://github.com/flutter/flutter/issues/34993

是的,这里有一个解决方案 https://github.com/flutter/flutter/issues/34993#issue-459900986

但这对我来说似乎太开销了,因为我不想为handler我的每个活动创建新的

还有其他解决方案吗?

4

3 回答 3

2

执行与上述建议解决方案相同的操作,但仅将其用于特定事件。

创建 ui 处理程序对象

public class BitcoinWalletPlugin implements MethodCallHandler, ... {

  private Handler uiThreadHandler = new Handler(Looper.getMainLooper());

  @Override
  public void onListen(Object o, EventChannel.EventSink eventSink) {
    switch (this.channel) {
      ...
      case CHANNEL_NAME:
        // before
        // bitcoinWallet.setOnStartupListener(() -> eventSink.success(true));

        // after
        bitcoinWallet.setOnStartupListener(() -> uiThreadHandler.post(() -> eventSink.success(true)));
        break;
    }
  }

}

于 2019-08-11T06:05:07.523 回答
0

对于 Kotlin,您可以独立包装回调runOnUiThread

runOnUiThread {
    result.success(identifier);
}
于 2021-11-21T08:47:48.163 回答
0

https://gist.github.com/yongjhih/e6c5634c775e49f01c71ee029d8beebf

fun Result.onMain(): ResultOnMain {
  return if (this is ResultOnMain) {
      this
  } else {
    ResultOnMain(this)
  }
}

class ResultOnMain internal constructor(private val result: Result) : Result {
  private val handler: Handler by lazy {
    Handler(Looper.getMainLooper())
  }

  override fun success(res: Any?) {
    handler.post { result.success(res) }
  }

  override fun error(
          errorCode: String, errorMessage: String?, errorDetails: Any?) {
    handler.post { result.error(errorCode, errorMessage, errorDetails) }
  }

  override fun notImplemented() {
    handler.post { result.notImplemented() }
  }
}
于 2020-04-28T21:52:43.437 回答