方法通道是否缓冲消息,直到另一端被"connected"?



我在Android方面有一个MethodChannel

    class MainActivity: FlutterActivity() {
      private var channel : MethodChannel? = null
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        GeneratedPluginRegistrant.registerWith(this)
        channel = MethodChannel(flutterView, "com.foo.Bar")
        channel!!.invokeMethod("onCreate", "created")
      }
    }

在飞镖方面,我做到了:

    void main() {
      _main();
    }
    Future<void> _main() async {
      ... // do some async init stuff

      const platform = MethodChannel('com.foo.Bar');
      platform.setMethodCallHandler((call) {
        print('com.foo.Bar');
        print(call.method);
        print(call.arguments);
        return null;
      });
      runApp(MyApp());
    }

运行代码时,我在应用程序日志中看不到相应的消息。

Android 端的MethodChannel是否缓冲消息,直到 Dart 端"连接"或消息以MainActivity.onCreate发送?

即使这个问题有点旧,我也发现自己处于类似的情况。

我已使用 android.intent.action.VIEW Intent 筛选器来允许我的应用打开文件。更准确地说,我想将打开的文件的内容交给飞镖代码进行处理。

由于打开文件会启动应用,因此在 dart 部件构建小部件树并创建方法通道之前,将调用方法调用。

因此,原生 Android 部分需要等到 Dart 部分准备就绪。这可以通过侦听渲染器来实现。

由于代码应该是可读的,因此在 FlutterRenderer 上使用扩展来提高代码的可读性:

fun FlutterRenderer.doAfterFirstRender(op: () -> Unit){
    // Check if flutter part is already available
    if (isDisplayingFlutterUi) {
        op()
    } else {
        addIsDisplayingFlutterUiListener(object :FlutterUiDisplayListener{
            override fun onFlutterUiNoLongerDisplayed() {
            }
            override fun onFlutterUiDisplayed() {
                removeIsDisplayingFlutterUiListener(this)
                op()
            }
        })
    }
} 

在代码中,您现在可以使用扩展轻松调用该方法:

override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        // Check if the intent was from file
        if (intent.action != null
                && intent.action.equals(Intent.ACTION_VIEW)
                && intent.data != null) {

            // get the file name & content
            val fileName = getFileName(intent.data)
            val fileExtension = fileName.orEmpty().split('.').last().toLowerCase()
            // check if the file extension is allowed
            if (fileExtension in ALLOWED_FILE_EXTENSIONS) {
                // get the file content
                val reader = BufferedReader(InputStreamReader(
                        context.contentResolver.openInputStream(intent.data)))
                val content = reader.readText()
                reader.close()
                val methodName = when (fileExtension) {
                    "ixml" -> "importDataFile"
                    "gxml" -> "importStructureFile"
                    else -> ""
                }
               flutterEngine.renderer.doAfterFirstRender {
                   MethodChannel(flutterEngine.dartExecutor.binaryMessenger, IMPORT_FILE_CHANNEL)
                           .invokeMethod(methodName, content)
               }
            }
        }
    } 

最新更新