React Native模块加载与原理分析

2,374 阅读9分钟

后面会陆续写一些文章分析React Native源码,今天分析下模块加载的过程,包括系统模块和用户自定义模块的加载。源码是基于0.19.1,加载的大概流程和0.54差别不大,所以小伙伴们也不用特别纠结。

首先先看下怎么自定义Java模块给JS调用。直接用的官方的ToastAndroid的例子了。 ###1.自定义模块 首先创建一个原生模块,原生模块是继承了ReactContextBaseJavaModule的Java类,它可以实现一些JavaScript所需的功能。

public class ToastModule extends ReactContextBaseJavaModule {

  private static final String DURATION_SHORT_KEY = "SHORT";
  private static final String DURATION_LONG_KEY = "LONG";

  public ToastModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @Override
  public String getName() {
    return "ToastExample";
  }

  @ReactMethod
  public void show(String message, int duration) {
    Toast.makeText(getReactApplicationContext(), message, duration).show();
  }

}

ReactContextBaseJavaModule要求派生类实现getName方法。这个函数用于返回一个字符串名字,这个名字在JavaScript端标记这个模块。这里我们把这个模块叫做ToastExample,这样就可以在JavaScript中通过React.NativeModules.ToastExample访问到这个模块。要导出一个方法给JavaScript使用,Java方法需要使用注解@ReactMethod。方法的返回类型必须为void。 这样模块就定义好了,接下来就是注册这个模块了。在Java层需要注册这个模块,在应用的Package类的createNativeModules方法中添加这个模块。如果模块没有被注册,它也无法在JavaScript中被访问到。

public class AnExampleReactPackage implements ReactPackage {

 @Override
 public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
   return Collections.emptyList();
 }

 @Override
 public List<NativeModule> createNativeModules(
                             ReactApplicationContext reactContext) {
   List<NativeModule> modules = new ArrayList<>();

   modules.add(new ToastModule(reactContext));

   return modules;
 }

这个package需要在MainApplication.java文件的getPackages方法中提供。这个文件位于你的react-native应用文件夹的android目录中。具体路径是: android/app/src/main/java/com/your-app-name/MainApplication.java.

public class MainApplication extends Application implements ReactApplication {
    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(),
                    new AnExampleReactPackage()
            );
        }

        @Override
        protected String getJSMainModuleName() {
            return "index.android";
        }

        @Nullable
        @Override
        protected String getBundleAssetName() {
            return "index.android.bundle";
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        MultiDex.install(this);
      ...
    }
}

这样就完成了模块的注册工作了,可以看出来框架的封装做的很好,可以很好的扩展组件的定义和注册。

不知道大家有没有疑问,反正我在刚做RN的时候做完上面的步骤后是有疑问的,模块怎么被加载的?RN的界面和Android原生的界面比如Activity有什么关系? 首先来看下,RN的界面和Android原生的界面比如Activity有什么关系? ###2.ReactActivity 大家都知道,在原生Android中肯定是有一个MainActivity,然后再onCreate中setContentView塞入我们在xml中定义的布局文件,这样界面就能被系统给绘制出来。那么RN的所有界面其实也可以放到一个布局文件中,只不过现在布局文件不是xml了,而是js写的文件了,然后把这个布局文件给到一个Activity中,空口无凭,去扒一扒源码。

首先在开发RN程序的时候要新建一个Activity继承于ReactActivity,比如下面这样:

 public class MainActivity extends ReactActivity implements DefaultHardwareBackBtnHandler {
        /**
         * Returns the name of the main component registered from JavaScript.
         * This is used to schedule rendering of the component.
         */
        @Override
        protected String getMainComponentName() {
            return "TEST";
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public void invokeDefaultOnBackPressed() {
            super.onBackPressed();
        }
    }

首先继承ReactActivity,把生命周期交给系统进行管理,其他工作通过Delegate完成。

看下ReactActivity,其中getMainComponentName方法需要进行重写,为什么需要重写?后面在代码里面分析,这里先略过。

/**
 * Base Activity for React Native applications.
 */
public abstract class ReactActivity extends Activity
    implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {

  private final ReactActivityDelegate mDelegate;

  protected ReactActivity() {
    mDelegate = createReactActivityDelegate();
  }

  /**
   * Returns the name of the main component registered from JavaScript.
   * This is used to schedule rendering of the component.
   * e.g. "MoviesApp"
   */
  protected @Nullable String getMainComponentName() {
    return null;
  }

  /**
   * Called at construction time, override if you have a custom delegate implementation.
   */
  protected ReactActivityDelegate createReactActivityDelegate() {
    return new ReactActivityDelegate(this, getMainComponentName());
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mDelegate.onCreate(savedInstanceState);
  }
  ...
}

getMainComponentName返回的名称需要和Android入口文件index.android.js里面注册的组件名称一致:

class TEST extends Component {
    render() {
        return <App />;
    }
}

AppRegistry.registerComponent('TEST', () => TEST);

其实到这里可以知道要渲染的组件就是TEST这个Component(RN中的组件,可以简单对等于View)。

接着返回去看ReactActivity,生命周期里面都调用ReactActivityDelegate:

protected void onCreate(Bundle savedInstanceState) {
        boolean needsOverlayPermission = false;
        //如果Android版本是M(23)也就是Android 6.0系统,在调式模式下需要弹窗获取权限
        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);
          }
        }
    
        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.");
        }
        mReactRootView = createRootView();
        mReactRootView.startReactApplication(
          getReactNativeHost().getReactInstanceManager(),
          appKey,
          getLaunchOptions());
        getPlainActivity().setContentView(mReactRootView);
      }

1.mMainComponentName就是前面重写方法需要返回的,如果复写了就会进入loadApp,这就是前面需要复写该方法的原因喽

3.loadApp进行三个很重要的工作,

  • 创建ReactRootView,这个是RN 的自定义根View,可以监听屏幕尺寸的变化,拦截Touch事件然后进行发送给JS层进行处理。最终会把这个View塞给activity的setContentView。看下官方的定义:
   Default root view for catalyst apps. Provides the ability to listen for 
size changes so that a UI manager can re-layout its elements. It delegates 
handling touch events for itself and child views and sending those events to 
JS by using JSTouchDispatcher. This view is overriding {@link
   ViewGroup#onInterceptTouchEvent} method in order to be notified about the events 
for all of its children and it's also overriding 
{@link ViewGroup#requestDisallowInterceptTouchEvent} to make sure that 
{@link ViewGroup#onInterceptTouchEvent} will get events even when some child view 
start intercepting it. In case when no child view is interested in handling 
some particular touch event this view's {@link View#onTouchEvent} will still 
return true in order to be notified about all subsequent touch events related to 
that gesture (in case when JS code want to handle that gesture
  • 创建ReactContext
Schedule rendering of the react component rendered by the JS application from the
given JS* module (@{param moduleName}) using provided 
{@param reactInstanceManager} to attach to the* JS context of that manager.
  • setContentView(ReactRootView)

到这里就明白主要工作在ReactActivityDelegate中的loadApp,首先构造根View-createRootView,然后构造ReactContext上下文,渲染appKey-- mMainComponentName这里就是在index.android.js中注册的入口模块,之后将该View塞给Activity,最终Android系统将其显示到屏幕上。

###3.RN框架加载Package 接下来看看Package怎么加载到RN框架中。

首先回到前面ReactActivityDelegate中的loadApp会拿到MainApplication中的ReactNativeHost:

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);
  }

protected ReactNativeHost getReactNativeHost() {
    return ((ReactApplication) getPlainActivity().getApplication()).getReactNativeHost();
  }

loadApp会调用getReactNativeHost().getReactInstanceManager(),接着看看ReactInstanceManager是什么,跟到ReactNativeHost中,第一次会构建ReactInstanceManager,用来管理CatalystInstance,CatalystInstance是Java/C++/JS三方通信的总管:

/**
   * Get the current {@link ReactInstanceManager} instance, or create one.
   */
  public ReactInstanceManager getReactInstanceManager() {
    if (mReactInstanceManager == null) {
      mReactInstanceManager = createReactInstanceManager();
    }
    return mReactInstanceManager;
  }

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();
  }

从上面可以看到用到了建造者模式构造 ReactInstanceManager:

/**
 * Builder class for {@link ReactInstanceManager}
 */
public class ReactInstanceManagerBuilder {

  private final List<ReactPackage> mPackages = new ArrayList<>();
  
  public ReactInstanceManagerBuilder addPackage(ReactPackage reactPackage) {
    mPackages.add(reactPackage);
    return this;
  }

  public ReactInstanceManagerBuilder addPackages(List<ReactPackage> reactPackages) {
    mPackages.addAll(reactPackages);
    return this;
  }
  
  /**
     * Instantiates a new {@link ReactInstanceManagerImpl}.
     * Before calling {@code build}, the following must be called:
     * <ul>
     * <li> {@link #setApplication}
     * <li> {@link #setJSBundleFile} or {@link #setJSMainModuleName}
     * </ul>
     */
    public ReactInstanceManager build() {
      return new ReactInstanceManagerImpl(
          Assertions.assertNotNull(
              mApplication,
              "Application property has not been set with this builder"),
          mJSBundleFile,
          mJSMainModuleName,
          mPackages,
          mUseDeveloperSupport,
          mBridgeIdleDebugListener,
          Assertions.assertNotNull(mInitialLifecycleState, "Initial lifecycle state was not set"),
          mUIImplementationProvider,
          mNativeModuleCallExceptionHandler);
    }
}

到这里系统定义的和我们自定义的ReactPackage都加载到ReactInstanceManageImpl中的mPackages中。 再返回前面ReactRootView startReactApplication,会调用mReactInstanceManager.createReactContextInBackground

//com/facebook/react/ReactRootView
public void startReactApplication(
      ReactInstanceManager reactInstanceManager,
      String moduleName,
      @Nullable Bundle initialProperties) {
    Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "startReactApplication");
    try {
      UiThreadUtil.assertOnUiThread();

      if (!mReactInstanceManager.hasStartedCreatingInitialContext()) {
        mReactInstanceManager.createReactContextInBackground();
      }

      attachToReactInstanceManager();

    } finally {
      Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
    }
  }

接着到ReactInstanceManagerImpl中:

//com/facebool/react/ReactInstanceManagerImpl
@ThreadConfined(UI)
  public void createReactContextInBackground() {
	......
    mHasStartedCreatingInitialContext = true;
    recreateReactContextInBackgroundInner();
  }

@ThreadConfined(UI)
  private void recreateReactContextInBackgroundInner() {
    ......
    UiThreadUtil.assertOnUiThread();

    if (mUseDeveloperSupport && mJSMainModulePath != null &&
      !Systrace.isTracing(TRACE_TAG_REACT_APPS | TRACE_TAG_REACT_JSC_CALLS)) {
      final DeveloperSettings devSettings = mDevSupportManager.getDevSettings();

      // If remote JS debugging is enabled, load from dev server.
      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();
      } else 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 dev server is down, disable the remote JS debugging.
                          devSettings.setRemoteJSDebugEnabled(false);
                          recreateReactContextInBackgroundFromBundleLoader();
                        }
                      }
                    });
              }
            });
      }
      return;
    }

    recreateReactContextInBackgroundFromBundleLoader();
  }

最后都会回调:

//com/facebool/react/ReactInstanceManagerImpl
private void recreateReactContextInBackground(
      JavaScriptExecutor.Factory jsExecutorFactory,
      JSBundleLoader jsBundleLoader) {
    UiThreadUtil.assertOnUiThread();

    ReactContextInitParams initParams =
        new ReactContextInitParams(jsExecutorFactory, jsBundleLoader);
    if (!mIsContextInitAsyncTaskRunning) {
      // No background task to create react context is currently running, create and execute one.
      ReactContextInitAsyncTask initTask = new ReactContextInitAsyncTask();
      initTask.execute(initParams);
      mIsContextInitAsyncTaskRunning = true;
    } else {
      // Background task is currently running, queue up most recent init params to recreate context
      // once task completes.
      mPendingReactContextInitParams = initParams;
    }
  }

会启动一个AsyncTask来构造ReactContext:

//com/facebool/react/ReactInstanceManagerImpl
/*
   * Task class responsible for (re)creating react context in the background. These tasks can only
   * be executing one at time, see {@link #recreateReactContextInBackground()}.
   */
  private final class ReactContextInitAsyncTask extends
      AsyncTask<ReactContextInitParams, Void, Result<ReactApplicationContext>> {
    @Override
    protected void onPreExecute() {
      if (mCurrentReactContext != null) {
        tearDownReactContext(mCurrentReactContext);
        mCurrentReactContext = null;
      }
    }

    @Override
    protected Result<ReactApplicationContext> doInBackground(ReactContextInitParams... params) {
      Assertions.assertCondition(params != null && params.length > 0 && params[0] != null);
      try {
        JavaScriptExecutor jsExecutor = params[0].getJsExecutorFactory().create();
        return Result.of(createReactContext(jsExecutor, params[0].getJsBundleLoader()));
      } catch (Exception e) {
        // Pass exception to onPostExecute() so it can be handled on the main thread
        return Result.of(e);
      }
    }

    @Override
    protected void onPostExecute(Result<ReactApplicationContext> result) {
      try {
        setupReactContext(result.get());
      } catch (Exception e) {
        mDevSupportManager.handleException(e);
      } finally {
        mIsContextInitAsyncTaskRunning = false;
      }
      ......
    }
  }

在doInBackground中构造ReactContext:

  • 构造ReactContext
  • 加载CoreModulesPackage,系统的核心模块
  • 加载用户自定义Packages
  • 构造NativeModuleRegistry,管理暴露给JS层的Java本地模块
  • 构造JavaScriptModulesConfig,存储JS层暴露给Java调用的JS模块
  • 构造CatalystInstanceImpl,三方总管
  • runJSBundle
    /**
       * @return instance of {@link ReactContext} configured a {@link CatalystInstance} set
       */
      private ReactApplicationContext createReactContext(
          JavaScriptExecutor jsExecutor,
          JSBundleLoader jsBundleLoader) {
        mSourceUrl = jsBundleLoader.getSourceUrl();
        NativeModuleRegistry.Builder nativeRegistryBuilder = new NativeModuleRegistry.Builder();
        JavaScriptModulesConfig.Builder jsModulesBuilder = new JavaScriptModulesConfig.Builder();
    
        //构造ReactContext
        ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext);
        if (mUseDeveloperSupport) {
          reactContext.setNativeModuleCallExceptionHandler(mDevSupportManager);
        }
    
        //加载CoreModulesPackage
        Systrace.beginSection(
            Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
            "createAndProcessCoreModulesPackage");
        try {
          CoreModulesPackage coreModulesPackage =
              new CoreModulesPackage(this, mBackBtnHandler, mUIImplementationProvider);
          processPackage(coreModulesPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder);
        } finally {
          Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
        }
    
        //加载用户自定义Packages
        for (ReactPackage reactPackage : mPackages) {
          Systrace.beginSection(
              Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
              "createAndProcessCustomReactPackage");
          try {
            processPackage(reactPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder);
          } finally {
            Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
          }
        }
    
        //构造NativeModuleRegistry
        Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "buildNativeModuleRegistry");
        NativeModuleRegistry nativeModuleRegistry;
        try {
           nativeModuleRegistry = nativeRegistryBuilder.build();
        } finally {
          Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
        }
    
        //构造JavaScriptModulesConfig
        Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "buildJSModuleConfig");
        JavaScriptModulesConfig javaScriptModulesConfig;
        try {
          javaScriptModulesConfig = jsModulesBuilder.build();
        } finally {
          Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
        }
    
        ...
        //构造CatalystInstanceImpl
        CatalystInstanceImpl.Builder catalystInstanceBuilder = new CatalystInstanceImpl.Builder()
            .setCatalystQueueConfigurationSpec(CatalystQueueConfigurationSpec.createDefault())
            .setJSExecutor(jsExecutor)
            .setRegistry(nativeModuleRegistry)
            .setJSModulesConfig(javaScriptModulesConfig)
            .setJSBundleLoader(jsBundleLoader)
            .setNativeModuleCallExceptionHandler(exceptionHandler);
    
        Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "createCatalystInstance");
        CatalystInstance catalystInstance;
        try {
          catalystInstance = catalystInstanceBuilder.build();
        } finally {
          Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
        }
    
        ......
        reactContext.initializeWithInstance(catalystInstance);
    
        //runJSBundle
        Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "runJSBundle");
        try {
          catalystInstance.runJSBundle();
        } finally {
          Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
        }
    
        ReactMarker.logMarker("CREATE_REACT_CONTEXT_END");
        return reactContext;
      }
    //加载模块
    private void processPackage(
          ReactPackage reactPackage,
          ReactApplicationContext reactContext,
          NativeModuleRegistry.Builder nativeRegistryBuilder,
          JavaScriptModulesConfig.Builder jsModulesBuilder) {
        for (NativeModule nativeModule : reactPackage.createNativeModules(reactContext)) {
          nativeRegistryBuilder.add(nativeModule);
        }
        for (Class<? extends JavaScriptModule> jsModuleClass : reactPackage.createJSModules()) {
          jsModulesBuilder.add(jsModuleClass);
        }
      }

CoreModulesPackage

封装了一些系统的核心模块,有NativeModules和JSModules

class CoreModulesPackage implements ReactPackage{
  @Override
  public List<NativeModule> createNativeModules(
      ReactApplicationContext catalystApplicationContext) {
    ......
    return Arrays.<NativeModule>asList(
        new AnimationsDebugModule(
            catalystApplicationContext,
            mReactInstanceManager.getDevSupportManager().getDevSettings()),
        new AndroidInfoModule(),
        new DeviceEventManagerModule(catalystApplicationContext, mHardwareBackBtnHandler),
        new ExceptionsManagerModule(mReactInstanceManager.getDevSupportManager()),
        new Timing(catalystApplicationContext),
        new SourceCodeModule(
            mReactInstanceManager.getSourceUrl(),
            mReactInstanceManager.getDevSupportManager().getSourceMapUrl()),
        uiManagerModule,
        new DebugComponentOwnershipModule(catalystApplicationContext));
  }
  
  @Override
  public List<Class<? extends JavaScriptModule>> createJSModules() {
    return Arrays.asList(
        DeviceEventManagerModule.RCTDeviceEventEmitter.class,
        JSTimersExecution.class,
        RCTEventEmitter.class,
        RCTNativeAppEventEmitter.class,
        AppRegistry.class,
        com.facebook.react.bridge.Systrace.class,
        DebugComponentOwnershipModule.RCTDebugComponentOwnership.class);
  }
}

public interface ReactPackage {

  /**
   * @param reactContext react application context that can be used to create modules
   * @return list of native modules to register with the newly created catalyst instance
   */
  List<NativeModule> createNativeModules(ReactApplicationContext reactContext);

  /**
   * @return list of JS modules to register with the newly created catalyst instance.
   *
   * IMPORTANT: Note that only modules that needs to be accessible from the native code should be
   * listed here. Also listing a native module here doesn't imply that the JS implementation of it
   * will be automatically included in the JS bundle.
   */
  List<Class<? extends JavaScriptModule>> createJSModules();

  /**
   * @return a list of view managers that should be registered with {@link UIManagerModule}
   */
  List<ViewManager> createViewManagers(ReactApplicationContext reactContext);
}

到这里就把所有的Java模块和JS模块传递给了CatalystInstanceImpl,这个是三方的中转模块,调用逻辑在这里中转。再之后就是Java<-->JS双方通信的原理了,后面专门的文章进行分析。

###4.总结 整个流程其实是:

  ReactActivity--->
  ReactActivityDelegate--->
         createRootView->
          getReactNativeHost->
          createReactInstanceManager->ReactInstanceManagerImpl
                  recreateReactContextInBackground->
                     1.构造ReactContext->
                     2.加载CoreModulesPackage->
                     3.加载用户自定义Packages->
                     4.构造CatalystInstanceImpl->
                     5.runJSBundle
          setContentView(mReactRootView)

React Native框架就是套一个自定义的根View-ReactRootView,在这个自定义View中创建ReactInstanceManager,ReactInstanceManager会构造ReactContext(包括JS运行环境和JSBundleLoader),同时加载系统和用户定义的Package,构造三方通信的中转站CatalystInstanceImpl,然后解释执行JSBundle,最后getPlainActivity().setContentView(mReactRootView)塞给Activity这样RN界面就显示到屏幕上了,而这个Activity的生命周期其实还是交给Android进行管理的。

后面会接着分析RN中Java与JS的通信原理,感兴趣的小伙伴们欢迎关注。

如果文章内容能够帮到你,帮忙点赞哈。

欢迎关注juexingzhe