跨语言通信——rn BatchedBridge

这是rn最传统的通信方式,基于0.64代码梳理。
整体看,仍然是基于跨语言interop能力额外搭建了一套通信方式。

方法定义和绑定

信道建立

双端的接口定义是割裂的,并没有一个地方做唯一类型验证。

js侧
  • 用了一个很奇怪(不熟悉js语法,别的语言没见过这个写法)的+method的方式定义方法,并传给TurboModuleRegistry
  • TurboModuleRegistry#getEnforcing->requireModule->NativeModules.js->根方法,初始化NativeModules->genModule,这里面会消费native产生的__fbBatchedBridgeConfig
  • 动态生成一个对象,根据上面定义的module,#genMethod->方法内容就是转调BatchedBridge#enqueueNativeCall
java侧
  • 启动流程略过->这里起了个新线程,CatalystInstanceImpl#initializeBridge->CatalystInstanceImpl.cpp#initializeBridge->buildNativeModuleList->new JavaNativeModule->ModuleRegistry#registerModules,这里持有了一个name to index to arrayItem(module)的映射关系
  • ProxyExecutor#initializeRuntime->ModuleRegistry#getConfig
    • JavaNativeModule#getMethods->JavaModuleWrapper.java#getMethodDescriptors->findMethods->反射methods并构建JavaMethodWrapper,把映射存下来
  • 接上文->把config存到js中的__fbBatchedBridgeConfig指针上

js call java

  • BatchedBridge#enqueueNativeCall,加入到_queue,注意这里的_queue是object[4][],相同index代表了一个调用->如果队列中有等待超过5ms的调用则,global.nativeFlushQueueImmediate->JSIExecutor.cpp#callNativeModules,这里会把jsi(是的BatchedBridge也是jsi)对象转成folly::dynamic,有内存拷贝->JsToNativeBridge#callNativeModules->MethodCall#parseMethodCalls->ModuleRegistry#callNativeMethod->JavaNativeModule#invoke,切到shadowThread->JavaModuleWrapper.java#invoke->JavaMethodWrapper#invoke处理数据,然后反射调用到真正方法

java call js

有一个callFunction,比较简单,不赘述。

类型约束及传输

类型见官网
传输主要两部分:jsi->folly::dynamic,folly::dynamic->ReadableNativeArray/Map。

js->c++

JSI的Value是个Union的封装,folly::dynamic也是个Union封装。
JSIDynamic.cpp#dynamicFromValue->dynamicFromValueShallow,这里会把需要深拷贝的类型加到一个栈里->依次把栈里的数据dynamicFromValueShallow。

c+±>java

主要是folly::hybrid,也是一个跨语言通信的小框架。以ReadableNativeArray为例。

方法定义和绑定

JNIEnv#registerNatives关联java和native方法。

数据传输

在传递数据的时候,把dynamic转成对应的jobject/jprimitive(addDynamicToJArray)。

gc

也是PhantomReference方案。为每个HybridData创建了一个PhantomReference(叫Destructor),然后加到了全局唯一的ReferenceQueue里。启动一个daemon线程,死循环清理这个queue里的reference。
不明就里,但是会有个全局变量持有所有的Destructor。逻辑上有一个很有意思的多线程优化:

  • Destructor会在构造线程先加入到一个treiber stack中,这个stack使用compareAndSwap做到了无锁。
  • 仅在DestructorThread,会把stack dump到一个无锁双向队列中。
    由此做到了无锁、线程安全的把所有的Destructor都集中到了队列中。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值