概念:
Flutter 會將資料通過 engine 層傳送到 native 層,native 處理完了之後會有一個結果返回,即callback,也就是BinaryMessenger
的 send
函式返回結果是一個 Future 型別的原因
反過來,改為 native 向 flutter 傳送訊息,flutter 返回結果,那麼返回的這部分就對應著接收訊息資料的實現,處理結果通過 callback 回撥給 native
Flutter 傳送訊息流程:
傳送過程從 send 開始,返回值是 Future,在 _sendPlatformMessage
中使用 Completer
將 Future 轉成了回撥函式:
Future<ByteData?> _sendPlatformMessage(String channel, ByteData? message) {
final Completer<ByteData?> completer = Completer<ByteData?>();
// ui.PlatformDispatcher.instance is accessed directly instead of using
// ServicesBinding.instance.platformDispatcher because this method might be
// invoked before any binding is initialized. This issue was reported in
// #27541. It is not ideal to statically access
// ui.PlatformDispatcher.instance because the PlatformDispatcher may be
// dependency injected elsewhere with a different instance. However, static
// access at this location seems to be the least bad option.
ui.PlatformDispatcher.instance.sendPlatformMessage(channel, message, (ByteData? reply) {
try {
completer.complete(reply);
} catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'services library',
context: ErrorDescription('during a platform message response callback'),
));
}
});
return completer.future;
}
透過呼叫 ui.PlatformDispatcher.instance.sendPlatformMessage
準備傳送訊息至 engine 層,再由engine 層與native 層進行訊息的處理,在Native 端,以android 為例,android 中也有一個類似於defaultBinaryMessenger
的物件platformMessageHandler
,handleMessageFromDart
方法接收Flutter 傳來的訊息,並在其中從 messageHandlers
中取出對應 channel 的 handler(通過 setMessageHandler 設定),呼叫其 onMessage
方法進行處理,replyId 也就是之前Flutter 在sendPlatformMessage
生成的 responseId,它被封裝成了 Reply,處理完訊息之後呼叫 Reply 的 reply 方法,將結果回傳給 flutter 的 _sendPlatformMessage
函式,並用Completer
進行回撥,完成傳送
Flutter 接收訊息流程:
基本上就是傳送流程的反過來,當然細節上會有不同的地方,由 Native 中的 send
函式開始,以 android 為例,DartMessenger
的send
方法,在send
方法中,callback 就被轉換成了 resposeId,且callback 被儲存在 pendingReplies 中,然後呼叫 flutterJNI.dispatchPlatformMessage
,通過 jni 呼叫 DispatchPlatformMessage
函式,傳送訊息至 engine 層,由engine 層與Flutter 層進行訊息的處理
最後在PlatformDispatcher
中呼叫 _dispatchPlatformMessage
來傳入訊息,並由PlatformMessageResponseCallback
callback 回撥至window.onPlatformMessage
,也就是在 ServicesBinding 中的 defaultBinaryMessenger.handlePlatformMessage
,接收到訊息之後,BinaryMessenger 需要選擇合適的 MessageHandler 處理訊息,最後經過 MessageHandler 處理之後會得到 ByteData 型別的處理結果,最終由 callback 將結果回傳給 Native