美文网首页
React Native通信原理源码分析

React Native通信原理源码分析

作者: 耗子_wo | 来源:发表于2019-12-15 00:50 被阅读0次

本文出自于两个重要的链接

https://www.jianshu.com/p/ccab1a94b637

https://www.jianshu.com/p/4c4e08211d83

感谢作者(juexingzhe)

兄弟姐妹们,如果你们时间很宝贵不想慢慢的去仔细看过程,那么我读完了这两个链接的内容可以大致做一个分享,有问题欢迎来提问:

前提1 Native到JavaScript步骤

https://www.jianshu.com/p/358be2303c5e

主要是通过JavaScriptModule来实现

前提2 JavaScript到Native步骤

https://blog.csdn.net/u011068702/article/details/82719163

主要是通过NativeModule来实现


React Native通信原理源码分析一(Native到JavaScript)

https://www.jianshu.com/p/ccab1a94b637

个人总结:

首先JavaScriptModule与NativeModule都是在应用层比如Android的JAVA层定义的,JavaScriptModule是定义了Native层怎么调用JavaScript,NativeModule是定义了Native层怎么被JavaScript调用。

一开始所有的NativeModule和JSModule在ReactInstanceManagerImpl中注册,所有的JavaScriptModules,并且都扫描存放在JavaScriptModulesConfig中,ReactInstanceManagerImpl将JavaScriptModulesConfig用来实例化catalystInstance;

catalystInstance的buildModulesConfigJSONProperty方法把JavaScriptModulesConfig,NativeModuleRegistry(所有的JavaScriptModule与NativeModule)都写入了__fbBatchedBridgeConfig全局对象里的两个属性:remoteModuleConfig和localModulesConfig,分别对应Java模块和JS模块,并且把这个通过Webkit的接口属性注入到了C++层的里面方便调用(因为JavaScript最终执行是在C++层,因为Android里面的WebKit,JavaScriptCore是在library的C++层,写入的是通过Webkit提供接口实现)

Java调用JS方法时统一分发到JavaScriptModuleInvocationHandler中的invoke进行处理,在invoke中其实就是调用mCatalystInstance.callFunction->ReactBridge.callFunction->最终__fbBatchedBridge.callFunctionReturnFlushedQueue.apply(null,{moduleId, methodId, arguments})的形式拼接一个apply的Javascript执行语句,最后调用jni/react/JSCHelpers.cpp的evaluateScript来执行(最终调用到WebKit来执行这句JS),JS端的__fbBatchedBridge就是BatchedBridge的属性,BatchedBridge就是一个MessageQueue对象,他在初始化的时候存放了__fbBatchedBridgeConfig的remoteModuleConfig(Native模块)与localModulesConfig(JS模块)最后调用到this.__callFunction(module, method, args)里面的moduleMethods[method].apply(moduleMethods, args)来进行调用,moduleMethods的来源就是被调用的JavaScript层通过registerCallableModule方法写入的属性(实现Native到JavaScript步骤里面JS的模块会做这个步骤)

React Native通信原理源码分析二 (JavaScript到Native)

https://www.jianshu.com/p/4c4e08211d83

首先JavaScript RN模块想执行一个Native方法比如(ToastAndroid.show())实际调用的是RN里面的NativeModules.js中的ToastAndroid模块 RCTToastAndroid.show(message, duration),一开始在JAVA层就有注册了这个模块的对象(public class ToastModule extends ReactContextBaseJavaModule), NativeModules.js其中const RemoteModules = BatchedBridge.RemoteModules就是Java层注册的供JS层调用的模块(这个可参考上面BatchedBridge一开始就初始化好了),接着会循环遍历RemoteModules将Module放入变量NativeModules中(里面就包括ToastAndroid模块)遍历会调用BatchedBridge.processModuleConfig(config, module.moduleID)方法里面最后调用_genMethod方法,这个里面会把对应module的所有相关方法都绑定到self.__nativeCall(module, method, args, resolve, (errorData)这个方法里面来(意思就是说module[methodName] = self.__nativeCall),

__nativeCall会调用到global.nativeFlushQueueImmediate(this._queue)这个是在JSCExecutor.cpp中注入的函数(回到了C++层),然后查找m_callback方法找到了dispatchCallbacksToJava方法里面makeJavaCall方法,里面需要调用方法 env->CallVoidMethod(callback, gCallbackMethod, call.moduleId, call.methodId, newArray.get()),然后到gCallbackMethod方法(JNI方法准备回到JAVA层),最终callback在Java层就是ReactCallback,ReactCallback的实现类是NativeModulesReactCallback,是CatalystInstanceImpl的内部类,然后调用到mJavaRegistry.call方法中,更具ModuleId找到了对应的ModuleDefinition,然后调用它的call方法(ModuleDefinition是NativeModuleRegistry的静态私有内部类,也是每个NativeModule的一层包装,意思就是说找到了对应的NativeModule)最终调用到了ModuleDefinition里面的MethodRegistration的method.invoke方法(ModuleDefinition初始化的时候会把相关Module的所有方法加一个List里面),最后通过反射mMethod.invoke(BaseJavaModule.this, mArguments)调用到BaseJavaModule的mMethod方法(BaseJavaModule就是业务层定义的的NativeModule)

  PS:由于C++ 不是很好所以看的时候有点费劲···

参考链接:

https://www.jianshu.com/p/358be2303c5e

https://blog.csdn.net/u011068702/article/details/82719163

https://juejin.im/post/5a6460f8f265da3e4f0a446d#heading-12

https://www.jianshu.com/p/ccab1a94b637

https://www.jianshu.com/p/4c4e08211d83

相关文章

网友评论

      本文标题:React Native通信原理源码分析

      本文链接:https://www.haomeiwen.com/subject/olqknctx.html