【Android】ReactNative Android端启动流程

@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 方法中主要做了三件事:

  1. 创建 RootView

  2. 调用 RootView 实例的 startReactApplication 方法,将 ReactInstanceManager 实例、appKey、启动时初始化参数作为参数传递过去

  3. 将 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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值