MethodChannel是否缓冲消息,直到另一端“连接”?

时间:2019-06-14 15:38:37

标签: flutter flutter-platform-channel

我在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")
      }
    }

在Dart方面,我这样做:

    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中发送消息?

1 个答案:

答案 0 :(得分:0)

即使这个问题有点老了,我也遇到了类似的情况。

我已使用android.intent.action.VIEW意向过滤器允许我的应用打开文件。更准确地说,我想将打开的文件的内容交给dart代码进行处理。

由于打开文件启动了应用程序,因此在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)
               }
            }
        }
    }