Является ли 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)
}
}
}
}