跨语言通信——flutter channel

flutter

是啥就不介绍了。。。这篇主要针对flutter channel,不涉及dart::ffi。主要是dart<->c++<->java的通信。

核心概念

  • BinaryMessenger:真正的信道,用来传输数据的
  • MethodCall:传输的数据内容,event和method都被认为是MethodCall
  • MessageCodec:用来序列化/反序列化数据

方法定义和绑定

所有的绑定都是在BinaryMessenger中,由于跨语言,所以实际代码是c++的。注意,只有setMethodHandler之后才算注册上了方法,只invoke并不会有注册。只关注defaultBinaryMessager(ServicesBinding.instance.defaultBinaryMessenger)

信道建立

dart侧

runApp->new WidgetsFlutterBinding->ServicesBinding#initInstances。
构建_DefaultBinaryMessenger,并将_DefaultBinaryMessenger#handlePlatformMessage赋值给Window#onPlatformMessage。

java侧

new FlutterEngine->new DartExecutor->new DartMessenger->DartExecutor#onAttachedToJNI->FlutterJNI#setPlatformMessageHandler(存到FlutterJNI上)
library_loader.cc->PlatformViewAndroid#Register->platform_view_android_jni_impl#Register->绑定FlutterJNI#handlePlatformMessage到native

方法声明

dart回调以channelName->function的形式存到了_DefaultBinaryMessenger中。
java回调以channelName->MethodCallHandler的形式存到了DartMessenger中。

dart call java

  • 构造MethodCall->StandardMethodCodec#encodeMethodCall ->构建WriteBuffer->StandardMessageCodec#writeValue。序列化后是个ByteData/Unit8List(内容是TLV),以bootstrap_natives.h的形式绑定到了c++。
  • _DefaultBinaryMessenger#send->_DefaultBinaryMessenger#_sendPlatformMessage->ui.Window#sendPlatformMessage->window.cc#SendPlatformMessage。
    • 前文提到的ByteData会在DartVM中直接解包出来bytes。new DartByteData->Dart_TypedDataAcquireData->Api::UnwrapTypedDataHandle。这里会直接把native对象作为数据强转。
    • 如果没理解错,TypedData一系列逻辑是直接通过native关键字将dart对象和native对象地址绑定到一起(typed_data_patch.dart、bootstrap_natives.cc中的宏)。然后把所有的dart方法以library#set_native_entry_symbol_resolver(Bootstrap#SetupNativeResolver)的方法转交给native 宏中生成的方法。
  • 接上文->Engine#HandlePlatformMessage->Shell#OnEngineHandlePlatformMessage->切到android主线程PlatformViewAndroid#HandlePlatformMessage,生成response handle并关联到自增id上->PlatformViewAndroidJNIImpl#FlutterViewHandlePlatformMessage->FlutterJNI.java#handlePlatformMessage->一路走到IncomingMethodCallHandler#onMessage(这里decode)。
  • reply过程:Reply#reply(这里encode)->FlutterJNI#invokePlatformMessageResponseCallback->platform_view_android_jni_impl->PlatformViewAndroid#InvokePlatformMessageResponseCallback(根据之前生成的自增id找到callback并回调,这个回调直接封装了dart handle,所以可以理解为切换线程并直接调到了dart)

java call dart

基本就是上述过程反过来,不赘述。

类型约束及传输

约束见官方文档
整体看,数据从原始对象直接填充到c++的bytes里,仅在把数据转换为语言对象时才有额外内存申请,内存是传输数据原始大小的三倍。
传输过程重点是序列化后的数据全部都集中到c++侧(DirectBuffer@java和ByteData@dart),利用vm的api进行interpo,避免过多数据拷贝。但是,数据仍然是以序列化(copy+1)->bytes->反序列化(copy+1,释放bytes)的方式进行,所以有相当规模的拷贝。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值