JS程序的入口,将当前APP对象注册到AppRegistry组件中,AppRegistry组件是js module
import { AppRegistry } from 'react-native'
...省略代码
AppRegistry.registerComponent('demo', () => Index)
# 启动流程
- 我们新建一个RN的项目,在原生代码中会生成
MainActivity和MainApplication两个Java类。顾名思义,MainAcitivity就是我们的Native的入口了, - 我们先来看下
MainApplication都做了哪些操作
public class MainApplication extends Application implements ReactApplication {
//ReactNativeHost:持有ReactInstanceManager实例,做一些初始化操作。
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
//SoLoader:加载C++底层库,准备解析JS。
SoLoader.init(this, /* native exopackage */ false);
}
}
}
我们再来看下MainActivity的代码
public class MainActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "demo";
}
}
可以看到其实是继承了
ReactActivity类,只是重写了getMainComponentName方法,有没有看出来,其方法的返回值和我们在JS端的值是一样的。如果不一致会怎么样,你可以自己试一下。
# ReactActivity
我们来看下
ReactActivity的方法的onCreate方法
public abstract class ReactActivity extends Activity
implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {
private final ReactActivityDelegate mDelegate;
...省略代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
}
ReactActivity全权委托给ReactActivityDelegate来处理
ReactActivityDelegate
public class ReactActivityDelegate {
protected void onCreate(Bundle savedInstanceState) {
// 弹框权限判断
boolean needsOverlayPermission = false;
if (getReactNativeHost().getUseDeveloperSupport() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Get permission to show redbox in dev builds.
if (!Settings.canDrawOverlays(getContext())) {
needsOverlayPermission = true;
Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getContext().getPackageName()));
FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
Toast.makeText(getContext(), REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
((Activity) getContext()).startActivityForResult(serviceIntent, REQUEST_OVERLAY_PERMISSION_CODE);
}
}
// 加载组建逻辑 mMainComponentName为getMainComponentName返回的值
if (mMainComponentName != null && !needsOverlayPermission) {
loadApp(mMainComponentName);
}
// 双击判断工具类
mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
}
protected void loadApp(String appKey) {
//空判断
if (mReactRootView != null) {
throw new IllegalStateException("Cannot loadApp while app is already running.");
}
// 创建 RN容器根视图
mReactRootView = createRootView();
mReactRootView.startReactApplication(
getReactNativeHost().getReactInstanceManager(),
appKey,
getLaunchOptions());
//将rootview添加入activity
getPlainActivity().setContentView(mReactRootView);
}
}
loadApp做了三件事:创建RootView、创建ReactApplication、创建ReactInstanceManager
# ReactRootView
ReactRootView是一个自定义的View,其父类是FrameLayout。因此,可以把RN看成是一个特殊的 “自定义View”。
我们来看下
startReactApplication方法
public void startReactApplication(
ReactInstanceManager reactInstanceManager,
String moduleName,
@Nullable Bundle initialProperties) {
...省略代码
try {
//在UI线程中进行
UiThreadUtil.assertOnUiThread();
Assertions.assertCondition(
mReactInstanceManager == null,
"This root view has already been attached to a catalyst instance manager");
// 赋值
mReactInstanceManager = reactInstanceManager;
mJSModuleName = moduleName;
mAppProperties = initialProperties;
// 判断ReactContext是否初始化,没有就异步进行初始化
if (!mReactInstanceManager.hasStartedCreatingInitialContext()) {
mReactInstanceManager.createReactContextInBackground();
}
//宽高计算完成后添加布局监听
attachToReactInstanceManager();
} finally {
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
}
}
startReactApplication中的三个参数
| 形参 | 描述 |
|---|---|
reactInstanceManager |
ReactInstanceManager类型,创建和管理CatalyInstance的实例 |
moduleName |
就是之前的组件名 |
initialProperties |
是Native向JS传递的数据,以后可能由POJO代替,默认是null,需要的话要重写createReactActivityDelegate ,并重写其中getLaunchOptions方法 |
startReactApplication中调用了ReactInstanceManager的createReactContextInBackground方法。
# ReactInstanceManager
public void createReactContextInBackground() {
//首次执行
mHasStartedCreatingInitialContext = true;
recreateReactContextInBackgroundInner();
}
该方法只会在
application中执行一次,JS重载时,会走recreateReactContextInBackground, 这两个方法最终都会调用recreateReactContextInBackgroundInner方法
| 形参 | 描述 |
|---|---|
jsExecutorFactory |
C++和JS双向通信的中转站 |
jsBundleLoader |
bundle加载器,根据ReactNativeHost中的配置决定从哪里加载bundle文件 |
runCreateReactContextOnNewThread中有一个核心方法createReactContext来创建ReactContext
这段代码比较长,它主要做了这几件事:
- 创建
JavaModule注册表和JavaScriptModule注册表,交给CatalystInstance管理。 - 处理
ReactPackage,将各自的Module放入对应的注册表中。 - 通过上面的各个参数创建
CatalystInstance实例。CatalystInstance关联ReactContext,开始加载JS Bundle
# CatalystInstance
我们来看下
CatalystInstance的实现类CatalystInstanceImpl的构造方法


