Home Article Practice RN启动流程1

RN启动流程1

2024-06-15 22:07  views:162  source:许某    

我们知道RN的页面也是依托Activity,React Native框架里有一个ReactActivity,它
就是我们RN页面的容器。ReactActivity里有个ReactRootView,正如它的名字那样,它就是R
eactActivity的root View,最终渲染出来的view都会添加到这个ReactRootView上
。ReactRootView调用自己的startReactApplication()方法启动了整个RN页面,在
启动的过程中先去创建页面上下文ReactContext,然后再去加载、执行并将JavaScript映射成Nat
ive Widget,最终一个RN页面就显示在了用户面前。整个RN页面的启动流程图如下所示:这个流程看起来有点
长,但实际上重要的东西并不多,我们当前只需要重点关注四个问题:ReactInstanceManager是如何被
创建的,它在创建的时候都初始化了哪些对象?RN页面上下文ReactContext在创建的过程中都做了什么,
都初始化了哪些对象?JS Bundle是如何被加载的?JS入口页面是如何被渲染出来的?2.1 创建
ReactInstanceManager我们先来看第一个问题,我们都知道要使用RN页面,就需要先初始化一个Re
actNativeHost,它是一个抽象类,ReactInstanceManager就是在这个类里被创建的,如
下所示:复制代码public abstract class ReactNativeHost { pr
otected ReactInstanceManager createReactInstanceManager
() { ReactInstanceManagerBuilder build
er = ReactInstanceManager.builder() //应用上下文
.setApplication(mApplication) //JSMainM
oduleP相当于应用首页的js Bundle,可以传递url从服务器拉取js Bundle
//当然这个只在dev模式下可以使用 .setJSMainModulePath(getJS
MainModuleName()) //是否开启dev模式 .setUse
DeveloperSupport(getUseDeveloperSupport()) //红
盒的回调 .setRedBoxHandler(getRedBoxHandler())
//JS执行器 .setJavaScriptExecutorFactory(ge
tJavaScriptExecutorFactory()) //自定义UI实现机制,这个我
们一般用不到 .setUIImplementationProvider(getUIImple
mentationProvider()) .setInitialLifecycleState
(LifecycleState.BEFORE_CREATE); //添加我们外面设置的P
ackage for (ReactPackage reactPackage : getPacka
ges()) { builder.addPackage(reactPackage);
} //获取js Bundle的加载路径 String jsBun
dleFile = getJSBundleFile(); if (jsBundleFile !=
null) { builder.setJSBundleFile(jsBundleFile)
; } else { builder.setBundleAssetName(A
ssertions.assertNotNull(getBundleAssetName()));
} return builder.build(); }}2.2 创建ReactCont
ext我们再来看第二个问题,ReactContext创建流程序列图如下所示:可以发现,最终创建ReactCon
text是createReactContext()方法,我们来看看它的实现。复制代码public class
ReactInstanceManager { private ReactApplicationC
ontext createReactContext( JavaScriptExecutor j
sExecutor, JSBundleLoader jsBundleLoader) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.crea
teReactContext()"); ReactMarker.logMarker(CREATE_
REACT_CONTEXT_START); //ReactApplicationContext是R
eactContext的包装类。 final ReactApplicationContext re
actContext = new ReactApplicationContext(mApplicationCo
ntext); //debug模式里开启异常处理器,就是我们开发中见到的调试工具(红色错误框
等) if (mUseDeveloperSupport) { reactConte
xt.setNativeModuleCallExceptionHandler(mDevSupportManag
er); } //创建JavaModule注册表 NativeMod
uleRegistry nativeModuleRegistry = processPackages(reac
tContext, mPackages, false); NativeModuleCallE
xceptionHandler exceptionHandler = mNativeModuleCallExc
eptionHandler != null ? mNativeModuleCallExcept
ionHandler : mDevSupportManager; /
/创建CatalystInstanceImpl的Builder,它是三端通信的管理类 Cataly
stInstanceImpl.Builder catalystInstanceBuilder = new Ca
talystInstanceImpl.Builder() .setReactQueueConf
igurationSpec(ReactQueueConfigurationSpec.createDefault
()) //JS执行器 .setJSExecutor(jsExecutor)
//Java Module注册表 .setRegistry(nativeMod
uleRegistry) //JS Bundle加载器 .setJSBundl
eLoader(jsBundleLoader) //Java Exception处理器
.setNativeModuleCallExceptionHandler(exceptionHand
ler); ReactMarker.logMarker(CREATE_CATALYST_IN
STANCE_START); // CREATE_CATALYST_INSTANCE_END is
in JSCExecutor.cpp Systrace.beginSection(TRACE_T
AG_REACT_JAVA_BRIDGE, "createCatalystInstance");
final CatalystInstance catalystInstance; //构建Cata
lystInstance实例 try { catalystInstance = c
atalystInstanceBuilder.build(); } finally {
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
ReactMarker.logMarker(CREATE_CATALYST_INSTANCE_EN
D); } if (mBridgeIdleDebugListener != nu
ll) { catalystInstance.addBridgeIdleDebugListen
er(mBridgeIdleDebugListener); } if (Systrac
e.isTracing(TRACE_TAG_REACT_APPS | TRACE_TAG_REACT_JS_V
M_CALLS)) { catalystInstance.setGlobalVariable(
"__RCTProfileIsProfiling", "true"); } React
Marker.logMarker(ReactMarkerConstants.PRE_RUN_JS_BUNDLE
_START); //开启加载执行JS Bundle catalystInstance
.runJSBundle(); //关联catalystInstance与reactContext
reactContext.initializeWithInstance(catalystInst
ance); return reactContext; } }在这个方法里完成了RN
页面上下文ReactContext的创建,我们先来看看这个方法的两个入参:JSCJavaScriptExecu
tor jsExecutor:JSCJavaScriptExecutor继承于JavaScriptExecut
or,当该类被加载时,它会自动去加载"reactnativejnifb.so"库,并会调用Native方法in
itHybrid()初始化C++层RN与JSC通信的框架。JSBundleLoader jsBundleLoa
der:缓存了JSBundle的信息,封装了上层加载JSBundle的相关接口,CatalystInstanc
e通过其简介调用ReactBridge去加载JS文件,不同的场景会创建不同的加载器,具体可以查看类JSBund
leLoader。可以看到在ReactContext创建的过程中,主要做了以下几件事情:构建ReactAppl
icationContext对象,ReactApplicationContext是ReactContext的包
装类。利用jsExecutor、nativeModuleRegistry、jsBundleLoader、exc
eptionHandler等参数构建CatalystInstance实例,作为以为三端通信的中枢。调用Cata
lystInstance的runJSBundle()开始加载执行JS。另一个重要的角色CatalystInst
ance出现了,前面我们也说过它是三端通信的中枢。关于通信的具体实现我们会在接下来的通信机制小节来讲述,我们先
来接着看JS的加载过程。



Disclaimer: The above articles are added by users themselves and are only for typing and communication purposes. They do not represent the views of this website, and this website does not assume any legal responsibility. This statement is hereby made! If there is any infringement of your rights, please contact us promptly to delete it.

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)