Является ли MethodChannel буферизировать сообщения до тех пор, пока другая сторона не будет "подключена"?

У меня есть MethodChannel на стороне Android:

    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());
    }

При запуске кода я не вижу соответствующих сообщений в журнале приложения.

Является MethodChannel на стороне Android буферизует сообщения до тех пор, пока сторона Dart не "подключится" или сообщение отправлено в MainActivity.onCreate?

0 ответов

Даже если вопрос постарше, я оказался в похожей ситуации.

Я использовал android.intent.action.VIEWФильтр намерений, позволяющий моему приложению открывать файлы. Точнее, я хотел передать содержимое открытого файла в код дротика для обработки.

Поскольку открытие файла запускает приложение, вызов метода будет вызываться до того, как часть дротика построит дерево виджетов и создаст канал метода.

Следовательно, нативной части 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)
               }
            }
        }
    } 
Другие вопросы по тегам