(源码版本:0.34,新版本(0.48)基本流程是不变的,建议跟着源码看看,哪个版本的倒影响不大)
这篇简单刨析一下React Native
是怎么在Android
上跑起来的,会从下面几个方面说说。
- 启动流程
- 通信机制
- 事件驱动
- 渲染原理
- 脚本执行
启动流程
React Native
在Android
上启动是从ReactRootView.startReactApplication
触发的,而ReactRootView
是继承FrameLayout
的,所以React Native
在Android
的操作都是在这个View
中进行的。
startReactApplication(ReactInstanceManager reactInstanceManager, String moduleName, @Nullable Bundle launchOptions)
这个方法参数第一个ReactInstanceManager
,实现是XReactInstanceManagerImpl
,可以理解在应用层对RN
的配置都是对这个类操作实现的。moduleName
是要启动的RN
的Component
的name
,是在js
的AppRegistry.registerComponent('xxx', () => App);
定义的。最后的launchOptions
是传过去的参数,可以在js
的Component
的props
中获取。
下一步到了mReactInstanceManager.createReactContextInBackground();
是在后台线程中创建RN
的ReactContext
上下文对象,然后到
//JavaScriptExecutor 默认就是jsc,如果的debug在chrome上时候,就是v8。
//JSBundleLoader 有AssetLoader FileLoader CachedBundleFromNetworkLoader RemoteDebuggerBundleLoader 从不同的地方加载bundle
private void recreateReactContextInBackground(
JavaScriptExecutor.Factory jsExecutorFactory,
JSBundleLoader jsBundleLoader) {
UiThreadUtil.assertOnUiThread();
ReactContextInitParams initParams =
new ReactContextInitParams(jsExecutorFactory, jsBundleLoader);
if (mReactContextInitAsyncTask == null) {
// No background task to create react context is currently running, create and execute one.
mReactContextInitAsyncTask = new ReactContextInitAsyncTask();
mReactContextInitAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, initParams);
} else {
// Background task is currently running, queue up most recent init params to recreate context
// once task completes.
mPendingReactContextInitParams = initParams;
}
}
主要的创建工作就转移到了ReactContextInitAsyncTask
这个AsyncTask
里面,
@Override
protected Result<ReactApplicationContext> doInBackground(ReactContextInitParams... params) {
....
return Result.of(createReactContext(jsExecutor, params[0].getJsBundleLoader()));
....
}
private ReactApplicationContext createReactContext(
JavaScriptExecutor jsExecutor,
JSBundleLoader jsBundleLoader) {
...
NativeModuleRegistry.Builder nativeRegistryBuilder = new NativeModuleRegistry.Builder();//NativeModule的注册表
JavaScriptModuleRegistry.Builder jsModulesBuilder = new JavaScriptModuleRegistry.Builder();//jsModules的注册表
...打包定义的各种modules到上面的注册表...
//创建关键的CatalystInstanceImpl
CatalystInstanceImpl.Builder catalystInstanceBuilder = new CatalystInstanceImpl.Builder()
...
catalystInstance = catalystInstanceBuilder.build();
....
//扔到js线程中加载js脚本
catalystInstance.getReactQueueConfiguration().getJSQueueThread().callOnQueue(
new Callable<Void>() {
@Override
public Void call() throws Exception {
//让reactContext持有catalystInstance
reactContext.initializeWithInstance(catalystInstance);
...
catalystInstance.runJSBundle();
return null;
}
}).get();
}
在CatalystInstanceImpl
的构造函数中有
...
//native C++方法,用来初始化JNI相关状态然后返回mHybridData。具体在 OnLoad.cpp 的 JSCJavaScriptExecutorHolder 类中
mHybridData = initHybrid();
...
//初始化线程环境,包括和主线程绑定,JS线程,Native线程创建。
mReactQueueConfiguration = ReactQueueConfigurationImpl.create(
ReactQueueConfigurationSpec,
new NativeExceptionHandler());
...
initializeBridge(
new BridgeCallback(this),//CatalystInstanceImpl内部类,用于native对java的一些回调
jsExecutor,//jsc
mReactQueueConfiguration.getJSQueueThread(),//js线程队列
mReactQueueConfiguration.getNativeModulesQueueThread(),//native线程队列
mJavaRegistry.getModuleRegistryHolder(this));//nativemodules注册表
mMainExecutorToken = getMainExecutorToken();//貌似是用于切换jsExecutor的标记,后面版本删掉了。
然后就进入到了cpp
层的CatalystInstanceImpl.cpp
的initializeBridge
方法
void CatalystInstanceImpl::initializeBridge(
jni::alias_ref<ReactCallback::javaobject> callback,
// This executor is actually a factory holder.
JavaScriptExecutorHolder* jseh,
jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,
jni::alias_ref<JavaMessageQueueThread::javaobject> moduleQueue,
ModuleRegistryHolder* mrh) {
instance_->initializeBridge(folly::make_unique<JInstanceCallback>(callback),
jseh->getExecutorFactory(),
folly::make_unique<JMessageQueueThread>(jsQueue),
folly::make_unique<JMessageQueueThread>(moduleQueue),
mrh->getModuleRegistry());
}
然后有委托给了Instance.cpp
的initializeBridge
方法
void Instance::initializeBridge(
std::unique_ptr<InstanceCallback> callback,
std::shared_ptr<JSExecutorFactory> jsef,
std::shared_ptr<MessageQueueThread> jsQueue,
std::unique_ptr<MessageQueueThread> nativeQueue,
std::shared_ptr<ModuleRegistry> moduleRegistry) {
callback_ = std::move(callback);
//在js线程中包装nativeQueue和创建nativeToJsBridge_,后者在双向bridge起作用,不要仅仅看名字,内部还有一个JsToNativeBridge
jsQueue->runOnQueueSync(
[this, &js