zoukankan      html  css  js  c++  java
  • flutter: 深入通信-接收端

    环境: flutter sdk v1.5.4-hotfix.1@stable

    对应 flutter engine: 52c7a1e849a170be4b2b2fe34142ca2c0a6fea1f

    前言

    通过PlatformChannel为平台层作为接收端的例子我们已经了解到DartMessenger通过响应接口handleMessageFromDart来把Dart层的消息/操作发送到平台层,而这个方法是PlatformMessageHandler这个接口对象的,持有接口实例的对象正是FlutterJNI

    作为被动调用的一方,平台层等待消息接收,并不知道消息的来源和用途,所以我们只需要按图索骥,找出调用方,就可追踪接收过程的完整流程。

    追溯

    容易看到FlutterJN.handlePlatformMessage调用了handleMessageFromDart,此函数被标记成@SuppressWarnings("unused"),很大可能与C++层有关了,搜索方法名称果然在``中找到"handlePlatformMessage", 函数签名是"(Ljava/lang/String;[BI)V"正是些方法,方法对象被全局变量g_handle_platform_message_method持有,又被FlutterViewHandlePlatformMessage引用, 至此又进入到C++层。

    这里HandlePlatformMessage这个名称实在太让人产生误解,感觉像是C++层在处理平台层发来的消息,然而实际却是传递Dart层的消息到平台,虽然handlePlatformXXX这种风格都表示处理Dart层的消息,并且保持的很好,但还是没有receiveXXX来的简单直观明了。

    为便于理解以下是被调用序列

    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。

    可知FlutterViewHandlePlatformMessage是C++调用的终点,全局变量g_handle_platform_message_method其实是平台java方法,所以需要知道java方法何时与C++方法关联起来的, 即g_handle_platform_message_method何时被设置的:
    以下是被调用序列

    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)中,表示被加载时执行的操作。

    结语

    结合前2篇的调用细节分析(精确到函数),及一些关键类的创建时机做一个简明flutter通道数据通信类图如下:
    左边是java类,右边是C++类

    FlutterChannel

  • 相关阅读:
    SQL SQL 连接 JOIN 例解。(左连接,右连接,全连接,内连接,交叉连接,自连接)[转]
    ADO.NET 1.基础(SqlCommand\ExecuteScalar\ExecuteReader\sqlDataAdapter)
    SQL 14.子查询
    winform 基础
    SQL – 12.索引 + 13.join
    判断是否为数字
    SQL 17.存储过程
    SQL 16.事务
    SQL 15.变量和流程控制
    SQL 18.触发器
  • 原文地址:https://www.cnblogs.com/lindeer/p/11119775.html
Copyright © 2011-2022 走看看