React-Native 版本: 0.52.0
React-Native 本质上来说其实就是一个普通的Android应用。通过Layout Inspector查看UI的层级结构如下:
一个普通的App。Java类一共有两个MainApplication和MainActivity。入口肯定也是MainApplication的onCreate,启动Activity就是MainActivity。
MainApplication
MainApplication很简单,实现了ReactApplication,构造一个ReactNativeHost。而ReactNativeHost就比较的复杂了,最重要的是创建并拥有了一个ReactInstanceManager。它还做一些native和js交互的一些配置,
例如getBundleAssetName()配置js入口的文件名字,getPackages()配置js与原生交互的模块组件等。
MainActivity
主要的工作在它的父类ReactActivity当中,这个很复杂,做了绝大多的事。
这里用了一个代理模式,ReactActivityDelegate代理了ReactActivity的生命周期的方法和其他一些方法,所以主要看ReactActivityDelegate的实现。
看看其代理的onCreate方法的实现:
protected void onCreate(Bundle savedInstanceState) {
if (mMainComponentName != null) {
loadApp(mMainComponentName);
}
mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
}
protected void loadApp(String appKey) {
if (mReactRootView != null) {
throw new IllegalStateException("Cannot loadApp while app is already running.");
}
//1.
mReactRootView = createRootView();
//2.
mReactRootView.startReactApplication(
getReactNativeHost().getReactInstanceManager(),
appKey,
getLaunchOptions());
//3/
getPlainActivity().setContentView(mReactRootView);
}
程序运行到这里和普通程序一样,创建一个View,然后setContentView。多了第2步。而第2步就是启动react-native.
所以重点看一下mReactRootView.startReactApplication()这个方法做了啥?
1.创建ReactInstanceManager
这个函数需第一个参数是ReactInstanceManager,这个是通过getReactNativeHost().getReactInstanceManager()来获取的,
getReactNativeHost()正是MainApplication里面返回的值。
getReactInstanceManager()第一次调用会创建,会调用createReactInstanceManager(),这个方法跟启动息息相关,所以也要重点看一下实现。
// ReactNativeHost.java
protected ReactInstanceManager createReactInstanceManager() {
ReactInstanceManagerBuilder builder = ReactInstanceManager.builder()
.setApplication(mApplication)
.setJSMainModulePath(getJSMainModuleName())
.setUseDeveloperSupport(getUseDeveloperSupport())
.setRedBoxHandler(getRedBoxHandler())
.setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
.setUIImplementationProvider(getUIImplementationProvider())
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE);
for (ReactPackage reactPackage : getPackages()) {
builder.addPackage(reactPackage);
}
String jsBundleFile = getJSBundleFile();
if (jsBundleFile != null) {
builder.setJSBundleFile(jsBundleFile);
} else {
builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
}
return builder.build();
}
这个方法将ReactNativeHost得到的Native的配置全部设置给ReactInstanceManager,然后调用build()。
build当中会调用ReactInstanceManager构造函数,所以代码转到ReactInstanceManager构造函数中
/* package */ ReactInstanceManager(
Context applicationContext,
@Nullable Activity currentActivity,
@Nullable DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler,
JavaScriptExecutorFactory javaScriptExecutorFactory,
@Nullable JSBundleLoader bundleLoader,
@Nullable String jsMainModulePath,
List packages,
boolean useDeveloperSupport,
@Nullable NotThreadSafeBridgeIdleDebugListener bridgeIdleDebugListener,
LifecycleState initialLifecycleState,
UIImplementationProvider uiImplementationProvider,
NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler,
@Nullable RedBoxHandler redBoxHandler,
boolean lazyNativeModulesEnabled,
boolean lazyViewManagersEnabled,
boolean delayViewManagerClassLoadsEnabled,
@Nullable DevBundleDownloadListener devBundleDownloadListener,
int minNumShakes,
int minTimeLeftInFrameForNonBatchedOperationMs) {
Log.d(ReactConstants.TAG, "ReactInstanceManager.ctor()");
initializeSoLoaderIfNecessary(applicationContext);
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(applicationContext);
mApplicationContext = applicationContext;
mCurrentActivity = currentActivity;
mDefaultBackButtonImpl = defaultHardwareBackBtnHandler;
mJavaScriptExecutorFactory = javaScriptExecutorFactory;
mBundleLoader = bundleLoader;
mJSMainModulePath = jsMainModulePath;
mPackages = new ArrayList<>();
mInitFunctions = new ArrayList<>();
mUseDeveloperSupport = useDeveloperSupport;
mDevSupportManager =
DevSupportManagerFactory.create(
applicationContext,
createDevHelperInterface(),
mJSMainModulePath,
useDeveloperSupport,
redBoxHandler,
devBundleDownloadListener,
minNumShakes);
mBridgeIdleDebugListener = bridgeIdleDebugListener;
mLifecycleState = initialLifecycleState;
mMemoryPressureRouter = new MemoryPressureRouter(applicationContext);
mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler;
mLazyNativeModulesEnabled = lazyNativeModulesEnabled;
mDelayViewManagerClassLoadsEnabled = delayViewManagerClassLoadsEnabled;
synchronized (mPackages) {
PrinterHolder.getPrinter()
.logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: Use Split Packages");
mPackages.add(
new CoreModulesPackage(
this,
new DefaultHardwareBackBtnHandler() {
@Override
public void invokeDefaultOnBackPressed() {
ReactInstanceManager.this.invokeDefaultOnBackPressed();
}
},
uiImplementationProvider,
lazyViewManagersEnabled,
minTimeLeftInFrameForNonBatchedOperationMs));
if (mUseDeveloperSupport) {
mPackages.add(new DebugCorePackage());
}
mPackages.addAll(packages);
}
// Instantiate ReactChoreographer in UI thread.
ReactChoreographer.initialize();
if (mUseDeveloperSupport) {
mDevSupportManager.startInspector();
}
}
一坨参数,我们寻找启动所以没必要研究个参数的构建,只要知道ReactInstanceManager在初次调用startReactApplication()的时候创建了就差不多了
2.创建ReactContext
因为主要看启动所以这里知道启动了一个ReactContext就够了
...
if (!mReactInstanceManager.hasStartedCreatingInitialContext()) {
mReactInstanceManager.createReactContextInBackground();
}
...
3.将ReactRootView绑定到ReactInstanceManager
绑定之后,最终会调用rootView的runApplication()
private void attachRootViewToInstance(
final ReactRootView rootView,
CatalystInstance catalystInstance) {
....
UIManagerModule uiManagerModule = catalystInstance.getNativeModule(UIManagerModule.class);
final int rootTag = uiManagerModule.addRootView(rootView);
rootView.setRootViewTag(rootTag);
rootView.runApplication();
.....
}
/* package */ void runApplication() {
......
CatalystInstance catalystInstance = reactContext.getCatalystInstance();
WritableNativeMap appParams = new WritableNativeMap();
appParams.putDouble("rootTag", getRootViewTag());
@Nullable Bundle appProperties = getAppProperties();
if (appProperties != null) {
appParams.putMap("initialProps", Arguments.fromBundle(appProperties));
}
mShouldLogContentAppeared = true;
String jsAppModuleName = getJSModuleName();
catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams);
......
}
runApplication最重要的就是
catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams);
这个了,这个会通过一个动态代理的方式构建出一个AppRegistry的代理类,然后代理类执行的runApplication
public synchronized T getJavaScriptModule(
CatalystInstance instance,
Class moduleInterface) {
JavaScriptModule module = mModuleInstances.get(moduleInterface);
if (module != null) {
return (T) module;
}
JavaScriptModule interfaceProxy = (JavaScriptModule) Proxy.newProxyInstance(
moduleInterface.getClassLoader(),
new Class[]{moduleInterface},
new JavaScriptModuleInvocationHandler(instance, moduleInterface));
.....
}
然后调用转到JavaScriptModuleInvocationHandler的invoke当中,最终会调用CatalystInstanceImpl的call()方法
void call(CatalystInstanceImpl catalystInstance) {
NativeArray arguments = mArguments != null ? mArguments : new WritableNativeArray();
catalystInstance.jniCallJSFunction(mModule, mMethod, arguments);
}
mModule就是js的AppRegistry ,mMethod 就是 runApplication ,方法会调用js模块中 AppRegistry的 runApplication。
到此Native的执行完毕。