@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List getPackages() {
return Arrays.asList(
new MainReactPackage()
);
}
@Override
protected String getJSMainModuleName() {
return “index”;
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
// 加载C++层渲染代码
SoLoader.init(this,false);
}
}
MainApplication 中主要完成了三件事:
-
(1)实现 ReactApplication 接口,重写 getReactNativeHost 方法,返回ReactNativeHost实例。
-
(2)定义并初始化 ReactNativeHost,实现 getUseDeveloperSupport、getPackages、getJSMainModuleName 方法,完成初始化设置。
-
(3)在 onCreate 生命周期方法中,调用SoLoader的init方法,启动C++层逻辑代码的初始化加载。
了解完两个文件,我们先从 MainActivity 开始分析。
MainActivity
MainActivity 继承 ReactActivity 类,重写了getMainComponentName 方法,并且方法的返回值需要和我们在JS端的值保持一致。
通过上面我们分析的 AppRegistry.js 中的 runApplication 方法发现:如果 getMainComponentName 中返回的名称与 RN 层 AppRegistry.registerComponent 注册名称不一致,会出现 Application XXX appKey has not been registered 异常。跟进 ReactActivity 类,看下核心代码:
package com.facebook.react;
/**
- Base Activity for React Native applications.
*/
public abstract class ReactActivity extends Activity implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {
private final ReactActivityDelegate mDelegate;
protected ReactActivity() {
mDelegate = createReactActivityDelegate();
}
/**
- 返回从JavaScript注册的主要组件的名称,用于组件的渲染。
*/
protected @Nullable String getMainComponentName() {
return null;
}
/**
- 在构造时调用,如果有自定义委托实现,则覆盖.
*/
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
… 中间省略生命周期、返回事件、权限申请函数
/**
- 获取 ReactNativeHost 实例
*/
protected final ReactNativeHost getReactNativeHost() {
return mDelegate.getReactNativeHost();
}
/**
- 获取 ReactInstanceManager 实例
*/
protected final ReactInstanceManager getReactInstanceManager() {
return mDelegate.getReactInstanceManager();
}
/**
- 加载 JSBundle
*/
protected final void loadApp(String appKey) {
mDelegate.loadApp(appKey);
}
}
ReactActivity类中主要完成这几件事:
-
(1)继承 Activity,实现 DefaultHardwareBackBtnHandler、PermissionAwareActivity 两个接口。重写其中的返回事件,及请求权限的方法。
-
(2)构造函数中调用 createReactActivityDelegate 方法,传入this、和 getMainComponentName 方法返回值,创建 ReactActivityDelegate实例。
-
(3)重写 Activity 生命周期方法,调用 delegate 实例的对应生命周期方法。
-
(4)定义获取 ReactNativeHost、ReactInstanceManager 实例方法。
-
(5)定义 loadApp方法。
可以看出ReactActivity采用了委托的方式,将所有的行为都交给ReactActivityDelegate去处理,降低耦合提升可扩展性,接下来我们瞎看ReactActivityDelegate是如何定义的
ReactActivityDelegate
package com.facebook.react;
/**
-
Delegate class for {@link ReactActivity} and {@link ReactFragmentActivity}. You can subclass this
-
to provide custom implementations for e.g. {@link #getReactNativeHost()}, if your Application
-
class doesn’t implement {@link ReactApplication}.
*/
public class ReactActivityDelegate {
private final @Nullable Activity mActivity;
private final @Nullable FragmentActivity mFragmentActivity;
private final @Nullable String mMainComponentName;
private @Nullable ReactRootView mReactRootView;
private @Nullable DoubleTapReloadRecognizer mDoubleTapReloadRecognizer;
…
public ReactActivityDelegate(Activity activity, @Nullable String mainComponentName) {
mActivity = activity;
mMainComponentName = mainComponentName;
mFragmentActivity = null;
}
public ReactActivityDelegate(
FragmentActivity fragmentActivity,
@Nullable String mainComponentName) {
mFragmentActivity = fragmentActivity;
mMainComponentName = mainComponentName;
mActivity = null;
}
protected @Nullable Bundle getLaunchOptions() {
return null;
}
protected ReactRootView createRootView() {
return new ReactRootView(getContext());
}
/**
-
Get the {@link ReactNativeHost} used by this app. By default, assumes
-
{@link Activity#getApplication()} is an instance of {@link ReactApplication} and calls
-
{@link ReactApplication#getReactNativeHost()}. Override this method if your application class
-
does not implement {@code ReactApplication} or you simply have a different mechanism for
-
storing a {@code ReactNativeHost}, e.g. as a static field somewhere.
*/
protected ReactNativeHost getReactNativeHost() {
return ((ReactApplication) getPlainActivity().getApplication()).getReactNativeHost();
}
public ReactInstanceManager getReactInstanceManager() {
return getReactNativeHost().getReactInstanceManager();
}
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.”);
}
mReactRootView = createRootView();
mReactRootView.startReactApplication(
getReactNativeHost().getReactInstanceManager(),
appKey,
getLaunchOptions());
getPlainActivity().setContentView(mReactRootView);
}
… 中间省略生命周期、返回事件、权限请求的方法
private Context getContext() {
if (mActivity != null) {
return mActivity;
}
return Assertions.assertNotNull(mFragmentActivity);
}
private Activity getPlainActivity() {
return ((Activity) getContext());
}
}
ReactActivityDelegate 类中主要完成这几件事:
-
(1)定义 getReactNativeHost、getReactInstanceManager 方法,获取对应实例。可以看到此处调用的是MainApplication中定义的ReactNativeHost实例。这里也就明白,为什么MainApplication需要实现ReactApplication接口,并重写 getReactNativeHost方法了。如果不实现 ReactApplication,可以把ReactNativeHost定义成全局静态常量即可。
-
(2)定义生命周期方法、返回事件方法、权限请求方法。并在方法中调用 ReactInstanceManager 中对应的方法。
-
(3)定义 createRootView 方法,在该方法中,通过 new ReactRootView,创建 ReactRootView 实例。
-
(4)在 onCreate 生命周期中,判断 mMainComponentName,如果不为 null,则执行 loadApp 方法。所以我们重点来看 loadApp 方法。
-
(5)在 loadApp 方法中主要做了三件事:
-
创建 RootView
-
调用 RootView 实例的 startReactApplication 方法,将 ReactInstanceManager 实例、appKey、启动时初始化参数作为参数传递过去
-
将 ReactRootView 设置为 MainActivity 布局视图
从 ReactActivityDelegate 方法中,我们了解到很多方法都交给了 ReactInstanceManager 实例去处理,ReactInstanceManager实例是通过 MainApplication 类中初始化的 ReactNativeHost 实例获取,在分析 ReactInstanceManager 之前,先跟进 ReactNativeHost 源码看一看:
ReactNativeHost
package com.facebook.react;
/**
- 包含 ReactInstanceManager 实例的简单类, 在 MainApplication 中定义 或 定义成静态字段使用。
*/
public abstract class ReactNativeHost {
private final Application mApplication;
private @Nullable ReactInstanceManager mReactInstanceManager;
protected ReactNativeHost(Application application) {
mApplication = application;
}
/**
- 获取 或 创建 ReactInstanceManager 实例
*/
public ReactInstanceManager getReactInstanceManager() {
if (mReactInstanceManager == null) {
mReactInstanceManager = createReactInstanceManager();
}
return mReactInstanceManager;
}
/**
- 获取此持有者是否包含{@link ReactInstanceManager}实例
*/
public boolean hasInstance() {
return mReactInstanceManager != null;
}
/**
- 销毁当前实例并释放对其的内部引用,允许它进行GCed
*/
public void clear() {
if (mReactInstanceManager != null) {
mReactInstanceManager.destroy();
mReactInstanceManager = null;
}
}
/**
- 创建 ReactInstanceManager 实例
*/
protected ReactInstanceManager createReactInstanceManager() {
ReactInstanceManagerBuilder builder = ReactInstanceManager.builder()
.setApplication(mApplication)
.setJSMainModulePath(getJSMainModuleName())
.setUseDeveloperSupport(getUseDeveloperSupport())
.setRedBoxHandler(getRedBoxHandler())
.setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
.setJSIModulesPackage(getJSIModulePackage())
.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()));
}
ReactInstanceManager reactInstanceManager = builder.build();
return reactInstanceManager;
}
protected final Application getApplication() {
return mApplication;
}