React-Native 本質上來說其實就是一個普通的Android應用。通過Layout Inspector查看UI的層級結構如下:
一個普通的App签赃。Java類一共有兩個MainApplication和MainActivity谷异。入口肯定也是MainApplication的onCreate,啟動Activity就是MainActivity锦聊。
MainApplication
MainApplication很簡單歹嘹,實現了ReactApplication,構造一個ReactNativeHost孔庭。而ReactNativeHost就比較的復雜了尺上,最重要的是創(chuàng)建并擁有了一個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);
}
程序運行到這里和普通程序一樣,創(chuàng)建一個View唉窃,然后setContentView耙饰。多了第2步。而第2步就是啟動react-native.
所以重點看一下mReactRootView.startReactApplication()這個方法做了啥纹份?
1.創(chuàng)建ReactInstanceManager
這個函數需第一個參數是ReactInstanceManager苟跪,這個是通過getReactNativeHost().getReactInstanceManager()來獲取的,
getReactNativeHost()正是MainApplication里面返回的值蔓涧。
getReactInstanceManager()第一次調用會創(chuàng)建,會調用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<ReactPackage> 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()的時候創(chuàng)建了就差不多了
2.創(chuàng)建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);
這個了鸠姨,這個會通過一個動態(tài)代理的方式構建出一個AppRegistry的代理類铜秆,然后代理類執(zhí)行的runApplication
public synchronized <T extends JavaScriptModule> T getJavaScriptModule(
CatalystInstance instance,
Class<T> 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的執(zhí)行完畢巍糯。