React Native Android 源码框架浅析(主流程及 Java 与 JS 双边通信)

本文详细剖析了React Native Android的启动流程,特别是`createReactContext()`方法中如何通过ReactPackage加载NativeModule和JavaScriptModule。核心在于通过CatalystInstanceImpl建立Java与JS之间的桥接,利用JNI和映射表实现模块调用。此外,还探讨了JS调用Java端的通信机制,展示了如何通过NativeModules获取Java模块并执行方法。
摘要由CSDN通过智能技术生成

coreModulesPackage,

reactContext,

moduleSpecs,

reactModuleInfoMap,

jsModulesBuilder);

} finally {

Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);

}

//加载我们自定义的ReactPackage,譬如自己封装的和MainReactPackage等,mPackages就来源于我们自己定义的;整个过程同上CoreModulesPackage,进行各种拼装module。

// TODO(6818138): Solve use-case of native/js modules overriding

for (ReactPackage reactPackage : mPackages) {

Systrace.beginSection(

TRACE_TAG_REACT_JAVA_BRIDGE,

“createAndProcessCustomReactPackage”);

try {

processPackage(

reactPackage,

reactContext,

moduleSpecs,

reactModuleInfoMap,

jsModulesBuilder);

} finally {

Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);

}

}

//!!!Java层模块注册表,通过它把所有的NativeModule注册到CatalystInstance。我们自定义的继承NativeModule接口的Java端也是通过他来管理。

NativeModuleRegistry nativeModuleRegistry;

try {

//new一个NativeModuleRegistry,其管理了NativeModule和OnBatchCompleteListener列表(JS调用Java结束时的回掉管理)。

nativeModuleRegistry = new NativeModuleRegistry(moduleSpecs, reactModuleInfoMap);

} finally {

Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);

ReactMarker.logMarker(BUILD_NATIVE_MODULE_REGISTRY_END);

}

//依据外面是否设置mNativeModuleCallExceptionHandler异常捕获实现来决定exceptionHandler是使用外面的还是DevSupportManager。

NativeModuleCallExceptionHandler exceptionHandler = mNativeModuleCallExceptionHandler != null

? mNativeModuleCallExceptionHandler
mDevSupportManager;

//!!!重点创建CatalystInstance的CatalystInstanceImpl实现实例

CatalystInstanceImpl.Builder catalystInstanceBuilder = new CatalystInstanceImpl.Builder()

.setReactQueueConfigurationSpec(ReactQueueConfigurationSpec.createDefault())

.setJSExecutor(jsExecutor)

.setRegistry(nativeModuleRegistry)

.setJSModuleRegistry(jsModulesBuilder.build())

.setJSBundleLoader(jsBundleLoader)

.setNativeModuleCallExceptionHandler(exceptionHandler);

final CatalystInstance catalystInstance;

try {

catalystInstance = catalystInstanceBuilder.build();

} finally {

Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);

ReactMarker.logMarker(CREATE_CATALYST_INSTANCE_END);

}

if (mBridgeIdleDebugListener != null) {

catalystInstance.addBridgeIdleDebugListener(mBridgeIdleDebugListener);

}

//关联reactContext与catalystInstance

reactContext.initializeWithInstance(catalystInstance);

//通过catalystInstance加载js bundle文件

catalystInstance.runJSBundle();

return reactContext;

}

可以发现,上面这段代码做的事情真特么多,不过总的来说 createReactContext() 方法做的都是一些取数据组表放表的过程,核心就是通过 ReactPackage 实现类的 createNativeModules()、createJSModules() 等方法把所有 NativeModule 包装后放入 NativeModuleRegistry 及 JavaScriptModule 包装后放入 JavaScriptModuleRegistry,然后把这两张映射表交给 CatalystInstanceImpl,同时包装创建 ReactContext 对象,然后通过 CatalystInstanceImpl 的 runJSBundle() 方法把 JS bundle 文件的 JS 代码加载进来等待 Task 结束以后调用 JS 入口进行渲染 RN。既然这样就去看看 CatalystInstanceImpl 的 build 方法中调用的 CatalystInstanceImpl 构造方法到底干了哪些鸟事,如下:

public class CatalystInstanceImpl implements CatalystInstance {

// C++ parts

private final HybridData mHybridData;

private native static HybridData initHybrid();

private CatalystInstanceImpl(

final ReactQueueConfigurationSpec ReactQueueConfigurationSpec,

final JavaScriptExecutor jsExecutor,

final NativeModuleRegistry registry,

final JavaScriptModuleRegistry jsModuleRegistry,

final JSBundleLoader jsBundleLoader,

NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler) {

FLog.d(ReactConstants.TAG, “Initializing React Xplat Bridge.”);

//native C++方法,用来初始化JNI相关状态然后返回mHybridData。

mHybridData = initHybrid();

//创建ReactNative的三个线程nativeModulesThread和jsThread、uiThread,都是通过Handler来管理的。

mReactQueueConfiguration = ReactQueueConfigurationImpl.create(

ReactQueueConfigurationSpec,

new NativeExceptionHandler());

mBridgeIdleListeners = new CopyOnWriteArrayList<>();

mJavaRegistry = registry;

mJSModuleRegistry = jsModuleRegistry;

mJSBundleLoader = jsBundleLoader;

mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler;

mTraceListener = new JSProfilerTraceListener(this);

//native C++方法,用来初始化Bridge。

initializeBridge(

new BridgeCallback(this),

jsExecutor,

mReactQueueConfiguration.getJSQueueThread(),

mReactQueueConfiguration.getNativeModulesQueueThread(),

mJavaRegistry.getModuleRegistryHolder(this));

mMainExecutorToken = getMainExecutorToken();

}

private native void initializeBridge(ReactCallback callback,

JavaScriptExecutor jsExecutor,

MessageQueueThread jsQueue,

MessageQueueThread moduleQueue,

ModuleRegistryHolder registryHolder);

}

刚刚分析 createReactContext() 方法的总结没错,CatalystInstanceImpl 这货就是个封装总管,负责了 Java 层代码到 JNI 封装初始化的任务和 Java 与 JS 调用的 Java 端控制中心。所以我们先看看调用 native initializeBridge 方法时传入的 5 个参数吧,分别如下:

1. callback参数: CatalystInstanceImpl 的内部静态实现类 BridgeCallback,负责相关接口回调回传。

2. jsExecutor参数: 前面分析的 XReactInstanceManagerImpl 中赋值为 JSCJavaScriptExecutor 实例,JSCJavaScriptExecutor 中也有自己的 native initHybrid 的 C++ 方法被初始化时调用,具体在 OnLoad.cpp 的 JSCJavaScriptExecutorHolder 类中。

3. jsQueue参数: 来自于 mReactQueueConfiguration.getJSQueueThread(),mReactQueueConfiguration就是 CatalystInstanceImpl 中创建的 ReactQueueConfigurationImpl.create(

ReactQueueConfigurationSpec,

new NativeExceptionHandler()); 第一个参数来自于 XReactInstanceManagerImpl 中 CatalystInstanceImpl 的建造者,实质为包装相关线程名字、类型等,然后通过 ReactQueueConfigurationImpl 的 create 创建对应线程的 Handler,这里就是名字为 js 的后台线程 Handler,第二个参数为异常捕获回调实现。

4. moduleQueue参数: 来自于 mReactQueueConfiguration.getNativeModulesQueueThread(),mReactQueueConfiguration就是 CatalystInstanceImpl 中创建的 ReactQueueConfigurationImpl.create(

ReactQueueConfigurationSpec,

new NativeExceptionHandler()); 第一个参数来自于 XReactInstanceManagerImpl 中 CatalystInstanceImpl 的建造者,实质为包装相关线程名字、类型等,然后通过 ReactQueueConfigurationImpl 的 create 创建对应线程的 Handler,这里就是名字为 native_modules 的后台线程 Handler,第二个参数为异常捕获回调实现。

5. registryHolder参数: mJavaRegistry 对象来自于 XReactInstanceManagerImpl 中 CatalystInstanceImpl 的建造者,通过 mJavaRegistry.getModuleRegistryHolder(this) 传递一个 Java 层的 ModuleRegistryHolder 实例到同名的 C++ 中,具体在 mJavaRegistry.getModuleRegistryHolder(this) 的返回值处为 return new ModuleRegistryHolder(catalystInstanceImpl, javaModules, cxxModules); 而 ModuleRegistryHolder 的构造方法中调用了 C++ 的 initHybrid(catalystInstanceImpl, javaModules, cxxModules); 方法。

CatalystInstanceImpl 这货会玩,自己在 Java 层直接把持住了 JavaScriptModuleRegistry 映射表,把 NativeModuleRegistry 映射表、BridgeCallback 回调、JSCJavaScriptExecutor、js 队列 MessageQueueThread、native 队列 MessageQueueThread 都通过 JNI 嫁接到了 C++ 中。那我们现在先把目光转移到 CatalystInstanceImpl.cpp 的 initializeBridge 方法上(关于 JNI 的 OnLoad 中初始化注册模块等等就不介绍了),如下:

void CatalystInstanceImpl::initializeBridge(

jni::alias_refReactCallback::javaobject callback,

// This executor is actually a factory holder.

JavaScriptExecutorHolder* jseh,

jni::alias_refJavaMessageQueueThread::javaobject jsQueue,

jni::alias_refJavaMessageQueueThread::javaobject moduleQueue,

ModuleRegistryHolder* mrh) {

// Java CatalystInstanceImpl -> C++ CatalystInstanceImpl -> Bridge -> Bridge::Callback

  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值