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