RN通信机制
我们先来理解一些基本的概念。JavaScript Module注册表说起JavaScript Module注册
表,我们需要先理解3个类/接口:JavaScriptModule、JavaScriptModuleRegist
ration、JavaScriptModuleRegistry。JavaScriptModule:这是一个接口
,JS Module都会继承此接口,它表示在JS层会有一个相同名字的js文件,该js文件实现了该接口定义的方法
,JavaScriptModuleRegistry会利用动态代理将这个接口生成代理类,并通过C++传递给JS层
,进而调用JS层的方法。JavaScriptModuleRegistration用来描述JavaScriptM
odule的相关信息,它利用反射获取接口里定义的Method。JavaScriptModuleRegistry
:JS Module注册表,内部维护了一个HashMap:HashMap<Class<? extends Ja
vaScriptModule>, JavaScriptModuleRegistration> mModuleR
egistrations,JavaScriptModuleRegistry利用动态代理生成接口JavaScri
ptModule对应的代理类,再通过C++传递到JS层,从而调用JS层的方法。Java Module注册表要理
解Java Module注册表,我们同样也需要理解3个类/接口:NativeModule、ModuleHold
er、NativeModuleRegistry。NativeModule:是一个接口,实现了该接口则可以被JS
层调用,我们在为JS层提供Java API时通常会继承BaseJavaModule/ReactContextB
aseJavaModule,这两个类就实现了NativeModule接口。ModuleHolder:Nativ
eModule的一个Holder类,可以实现NativeModule的懒加载。NativeModuleRegi
stry:Java Module注册表,内部持有Map:Map<Class<? extends NativeM
odule>, ModuleHolder> mModules,NativeModuleRegistry可以遍历
并返回Java Module供调用者使用。4.1 创建注册表关于NativeModuleRegistry和Ja
vaScriptModuleRegistry的创建,我们前面都已经提到管,大家还都记得吗。NativeModu
leRegistry是在createReactContext()方法里构建的。JavaScriptModule
Registry是在CatalystInstanceImpl的构建方法里构建的。这些都是在CatalystIn
stanceImpl的构建方法里通过native方法initializeBridge()传入了C++层,如下所
示:CatalystInstanceImpl.cpp复制代码void CatalystInstanceImpl
::initializeBridge( jni::alias_ref<ReactCallback::ja
vaobject> callback, // This executor is actually a f
actory holder. JavaScriptExecutorHolder* jseh, jn
i::alias_ref<JavaMessageQueueThread::javaobject> jsQueu
e, jni::alias_ref<JavaMessageQueueThread::javaobject
> moduleQueue, jni::alias_ref<jni::JCollection<JavaM
oduleWrapper::javaobject>::javaobject> javaModules,
jni::alias_ref<jni::JCollection<ModuleHolder::javaobjec
t>::javaobject> cxxModules) { instance_->initializeBri
dge(folly::make_unique<JInstanceCallback>(callback),
jseh->getExecutorFactory(),
folly::make_unique<JMessag
eQueueThread>(jsQueue), fo
lly::make_unique<JMessageQueueThread>(moduleQueue),
buildModuleRegistry(std::weak
_ptr<Instance>(instance_),
javaModules, cxxModules));}这个方法的参数
含义如下所示:ReactCallback callback:CatalystInstanceImpl的静态内部
类ReactCallback,负责接口回调。JavaScriptExecutor jsExecutor:JS执
行器,将JS的调用传递给C++层。MessageQueueThread jsQueue.getJSQueueT
hread():JS线程,通过mReactQueueConfiguration.getJSQueueThrea
d()获得,mReactQueueConfiguration通过ReactQueueConfiguration
Spec.createDefault()创建。MessageQueueThread moduleQueue:N
ative线程,通过mReactQueueConfiguration.getNativeModulesQueu
eThread()获得,mReactQueueConfiguration通过ReactQueueConfigu
rationSpec.createDefault()创建。Collection javaModules:jav
a modules,来源于mJavaRegistry.getJavaModules(this)。Collect
ion cxxModules):c++ modules,来源于mJavaRegistry.getCxxModu
les()。我们注意这些传入了两个集合:javaModules:传入的是Collection ,JavaMod
uleWrapper是NativeHolder的一个Wrapper类,它对应了C++层JavaModuleWr
apper.cpp,JS在Java的时候最终会调用到这个类的inovke()方法上。cxxModules:传入
的是Collection ,ModuleHolder是NativeModule的一个Holder类,可以实现N
ativeModule的懒加载。复制代码这两个集合在CatalystInstanceImpl::initial
izeBridge()被打包成ModuleRegistry传入Instance.cpp.、,如下所示:**Mo
duleRegistryBuilder.cpp**```javastd::unique_ptr<ModuleR
egistry> buildModuleRegistry( std::weak_ptr<Instance
> winstance, jni::alias_ref<jni::JCollection<JavaMod
uleWrapper::javaobject>::javaobject> javaModules, jn
i::alias_ref<jni::JCollection<ModuleHolder::javaobject>
::javaobject> cxxModules) { std::vector<std::unique_pt
r<NativeModule>> modules; for (const auto& jm : *javaM
odules) { modules.emplace_back(folly::make_unique<Ja
vaNativeModule>(winstance, jm)); } for (const auto& c
m : *cxxModules) { modules.emplace_back( folly:
:make_unique<CxxNativeModule>(winstance, cm->getName(),
cm->getProvider())); } if (modules.empty()) { ret
urn nullptr; } else { return folly::make_unique<Mod
uleRegistry>(std::move(modules)); }}打包好的ModuleRegistry
通过Instance::initializeBridge()传入到NativeToJsBridge.cpp中,
并在NativeToJsBridge的构造方法中传给JsToNativeBridge,以后JS如果调用Java
就可以通过ModuleRegistry来进行调用。这里的NativeToJsBridge.cpp与JsToNa
tiveBridge.cpp就是Java与JS相互调用的通信桥,我们来看看它们的通信方式。4.2 创建通信桥关
于整个RN的通信机制,可以用一句话来概括:JNI作为C++与Java的桥梁,JSC作为C++与JavaScri
pt的桥梁,而C++最终连接了Java与JavaScript。RN应用通信桥结构图如下所示:理解了整个通信桥的
结构,Java与JS是如何互相掉用的就很清晰了。Java调用JSJS调用Java