当前分析的ReactNative版本为:0.61.5:
ReactNative中最核心的当属ReactContext,想访问ReactNative框架相关类,第一个需要的就是ReactContext。
原生层定义NativeModule, 我们往往直接继承ReactContextBaseJavaModule,而该类构造函数传入的参数就是ReactApplicationContext,再来看看它的定义,原来它的父类就是ReactContext。
既然ReactContext如此重要,那么我们就来看看它是如何创建的。
在介绍之前,我们先介绍ReactInstanceManager,该类核心职责之一就是创建ReactContext,而创建的入口方法就是createReactContextInBackground,代码如下:
/**
* Trigger react context initialization asynchronously in a background async task. This enables
* applications to pre-load the application JS, and execute global code before {@link
* ReactRootView} is available and measured.
*
* <p>Called from UI thread.
*/
@ThreadConfined(UI)
public void createReactContextInBackground() {
Log.d(ReactConstants.TAG, "ReactInstanceManager.createReactContextInBackground()");
UiThreadUtil
.assertOnUiThread(); // Assert before setting mHasStartedCreatingInitialContext = true
if (!mHasStartedCreatingInitialContext) {
mHasStartedCreatingInitialContext = true;
recreateReactContextInBackgroundInner();
}
}
该方法是ReactContext创建的入口,接着看recreateReactContextInBackgroundInner方法:
@ThreadConfined(UI)
private void recreateReactContextInBackgroundInner() {
Log.d(ReactConstants.TAG, "ReactInstanceManager.recreateReactContextInBackgroundInner()");
PrinterHolder.getPrinter()
.logMessage(ReactDebugOverlayTags.RN_CORE, "RNCore: recreateReactContextInBackground");
UiThreadUtil.assertOnUiThread();
if (mUseDeveloperSupport && mJSMainModulePath != null) {
final DeveloperSettings devSettings = mDevSupportManager.getDevSettings();
if (!Systrace.isTracing(TRACE_TAG_REACT_APPS | TRACE_TAG_REACT_JS_VM_CALLS)) {
if (mBundleLoader == null) {
mDevSupportManager.handleReloadJS();
} else {
mDevSupportManager.isPackagerRunning(
new PackagerStatusCallback() {
@Override
public void onPackagerStatusFetched(final boolean packagerIsRunning) {
UiThreadUtil.runOnUiThread(
new Runnable() {
@Override
public void run() {
if (packagerIsRunning) {
mDevSupportManager.handleReloadJS();
} else if (mDevSupportManager.hasUpToDateJSBundleInCache()
&& !devSettings.isRemoteJSDebugEnabled()) {
// If there is a up-to-date bundle downloaded from server,
// with remote JS debugging disabled, always use that.
onJSBundleLoadedFromServer(null);
} else {
// If dev server is down, disable the remote JS debugging.
devSettings.setRemoteJSDebugEnabled(false);
recreateReactContextInBackgroundFromBundleLoader();
}
}
});
}
});
}
return;
}
}
recreateReactContextInBackgroundFromBundleLoader();
}
接着看recreateReactContextInBackgroundFromBundleLoader方法:
@ThreadConfined(UI)
private void recreateReactContextIn