React Native开发经验集React Native开发Android开发经验谈

React Native模块加载与原理分析

2018-04-02  本文已影响343人  juexingzhe

后面会陆续写一些文章分析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进行三个很重要的工作,

   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
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.

到这里就明白主要工作在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:

    /**
       * @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的通信原理,感兴趣的小伙伴们欢迎关注。

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

欢迎关注公众号:JueCode

上一篇下一篇

猜你喜欢

热点阅读