iT邦幫忙

2021 iThome 鐵人賽

DAY 8
0
Mobile Development

Flutter - 從 Packages & Plugins 掌握原生系列 第 8

Day08 Flutter 和 Native 通訊的原理 02

  • 概念:

    Flutter 會將資料通過 engine 層傳送到 native 層,native 處理完了之後會有一個結果返回,即callback,也就是BinaryMessengersend 函式返回結果是一個 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的物件platformMessageHandlerhandleMessageFromDart方法接收Flutter 傳來的訊息,並在其中從messageHandlers 中取出對應 channel 的 handler(通過 setMessageHandler 設定),呼叫其 onMessage 方法進行處理,replyId 也就是之前Flutter 在sendPlatformMessage生成的 responseId,它被封裝成了 Reply,處理完訊息之後呼叫 Reply 的 reply 方法,將結果回傳給 flutter 的 _sendPlatformMessage 函式,並用Completer進行回撥,完成傳送

    Flutter 接收訊息流程:

    基本上就是傳送流程的反過來,當然細節上會有不同的地方,由 Native 中的 send 函式開始,以 android 為例,DartMessengersend 方法,在send方法中,callback 就被轉換成了 resposeId,且callback 被儲存在 pendingReplies 中,然後呼叫 flutterJNI.dispatchPlatformMessage,通過 jni 呼叫 DispatchPlatformMessage 函式,傳送訊息至 engine 層,由engine 層與Flutter 層進行訊息的處理

    最後在PlatformDispatcher中呼叫 _dispatchPlatformMessage來傳入訊息,並由PlatformMessageResponseCallbackcallback 回撥至window.onPlatformMessage,也就是在 ServicesBinding 中的 defaultBinaryMessenger.handlePlatformMessage,接收到訊息之後,BinaryMessenger 需要選擇合適的 MessageHandler 處理訊息,最後經過 MessageHandler 處理之後會得到 ByteData 型別的處理結果,最終由 callback 將結果回傳給 Native


上一篇
Day07 Flutter 和 Native 通訊的原理 01
下一篇
Day09 Platform Channel - BasicMessageChannel
系列文
Flutter - 從 Packages & Plugins 掌握原生30

尚未有邦友留言

立即登入留言