flutter: 深刻通訊-接收端

環境: flutter sdk v1.5.4-hotfix.1@stablejava

對應 flutter engine: 52c7a1e849a170be4b2b2fe34142ca2c0a6fea1fandroid

前言

經過PlatformChannel爲平臺層做爲接收端的例子咱們已經瞭解到DartMessenger經過響應接口handleMessageFromDart來把Dart層的消息/操做發送到平臺層,而這個方法是PlatformMessageHandler這個接口對象的,持有接口實例的對象正是FlutterJNIgit

做爲被動調用的一方,平臺層等待消息接收,並不知道消息的來源和用途,因此咱們只須要按圖索驥,找出調用方,就可追蹤接收過程的完整流程。github

追溯

容易看到FlutterJN.handlePlatformMessage調用了handleMessageFromDart,此函數被標記成@SuppressWarnings("unused"),很大可能與C++層有關了,搜索方法名稱果真在``中找到"handlePlatformMessage", 函數簽名是"(Ljava/lang/String;[BI)V"正是些方法,方法對象被全局變量g_handle_platform_message_method持有,又被FlutterViewHandlePlatformMessage引用, 至此又進入到C++層。bash

這裏HandlePlatformMessage這個名稱實在太讓人產生誤解,感受像是C++層在處理平臺層發來的消息,然而實際倒是傳遞Dart層的消息到平臺,雖然handlePlatformXXX這種風格都表示處理Dart層的消息,而且保持的很好,但仍是沒有receiveXXX來的簡單直觀明瞭。函數

爲便於理解如下是被調用序列post

DartMessenger.handleMessageFromDart => PlatformMessageHandler
  FlutterJNI.handlePlatformMessage => g_handle_platform_message_method
    FlutterViewHandlePlatformMessage 
      PlatformViewAndroid::HandlePlatformMessage <= PlatformView::HandlePlatformMessage
       ...Shell::OnEngineHandlePlatformMessage <= PlatformView::Delegate::OnEngineHandlePlatformMessage
         Engine::HandlePlatformMessage <= RuntimeDelegate::HandlePlatformMessage
           RuntimeController::HandlePlatformMessage <= WindowClient::HandlePlatformMessage
             ::SendPlatformMessage
             ...tonic::DartCallStatic(::_SendPlatformMessage
             ...Window::RegisterNatives
複製代碼

這與發送端的序列層次徹底同樣,從上到下分別是Shell -> PlatformView -> Engine -> RuntimeController -> Window。spa

可知FlutterViewHandlePlatformMessage是C++調用的終點,全局變量g_handle_platform_message_method實際上是平臺java方法,因此須要知道java方法什麼時候與C++方法關聯起來的, 即g_handle_platform_message_method什麼時候被設置的: 如下是被調用序列code

g_handle_platform_message_method = env->GetMethodID(,"handlePlatformMessage",)
  ::RegisterApi
    PlatformViewAndroid::Register
      JNI_OnLoad
        System.loadLibrary("flutter") (library_loader.cc:23)
          FlutterMain.startInitialization (FlutterMain.java:161)
            FlutterApplication.onCreate (FlutterApplication.java:22)
複製代碼

JNI_OnLoad被聲明在了連接器腳本(android_exports.lst)中,表示被加載時執行的操做。orm

結語

結合前2篇的調用細節分析(精確到函數),及一些關鍵類的建立時機作一個簡明flutter通道數據通訊類圖以下: 左邊是java類,右邊是C++類

Flutter-Channel.jpg
相關文章
相關標籤/搜索