react-native源码分析系列二

本文详细解析了ReactContext初始化的过程,包括如何在ReactInstanceManager中创建ReactContext,以及如何通过CatalystInstance建立Java与JS之间的通信通道。重点分析了核心包和MainReactPackage中的模块注册,以及如何通过processPackage函数配置Java和JS模块。同时,文章通过一个具体的runApplication例子,展示了Java如何调用JS代码,并深入探讨了如何在native层调用js代码的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上篇。从ReactInstanceManager的createReactContext函数开始分析。

ReactInstanceManager.java
/**
* @return instance of {@link ReactContext} configured a {@link CatalystInstance} set
*/
private ReactApplicationContext createReactContext(
   JavaScriptExecutor jsExecutor,JSBundleLoader jsBundleLoader) {
  NativeModuleRegistry.Builder nativeRegistryBuilder = new NativeModuleRegistry.Builder();      //注册(暴露给js的)native模块
  JavaScriptModulesConfig.Builder jsModulesBuilder = new JavaScriptModulesConfig.Builder();  //注册(暴露给native的)js模块
  ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext);
  if (mUseDeveloperSupport) {
   reactContext.setNativeModuleCallExceptionHandler(mDevSupportManager);     //设置调试manager
  }
  CoreModulesPackage coreModulesPackage =newCoreModulesPackage(this,mBackBtnHandler);
 processPackage(coreModulesPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder);  //配置核心包
                                      //这个处理函数下面有分析
  for (ReactPackage reactPackage : mPackages) {          //mPackage-->new MainPackage
   processPackage(reactPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder);            //配置main包
  }
  CatalystInstance.Builder catalystInstanceBuilder = new CatalystInstance.Builder()                    //调度类
     .setCatalystQueueConfigurationSpec(CatalystQueueConfigurationSpec.createDefault())
     .setJSExecutor(jsExecutor)
     .setRegistry(nativeRegistryBuilder.build())
     .setJSModulesConfig(jsModulesBuilder.build())
     .setJSBundleLoader(jsBundleLoader)
     .setNativeModuleCallExceptionHandler(mDevSupportManager);
  CatalystInstance catalystInstance = catalystInstanceBuilder.build();        //这里其实就打通了java调用js代码 js调java的通道
  if (mBridgeIdleDebugListener != null) {                                                                        //其他不大重要的初始化过程
   catalystInstance.addBridgeIdleDebugListener(mBridgeIdleDebugListener);
  }
  reactContext.initializeWithInstance(catalystInstance);   
  catalystInstance.initialize();
  mDevSupportManager.onNewReactContextCreated(reactContext);
  moveReactContextToCurrentLifecycleState(reactContext);                                      //其他不大重要的初始化过程
  return reactContext; 

private voidprocessPackage(                         //处理函数
   ReactPackage reactPackage,
   ReactApplicationContext reactContext,
   NativeModuleRegistry.Builder nativeRegistryBuilder,
   JavaScriptModulesConfig.Builder jsModulesBuilder) {
  for (NativeModule nativeModule :reactPackage.createNativeModules(reactContext)) {
   nativeRegistryBuilder.add(nativeModule);                //保存native包 可getModule的时候取出
  }
  for (Class<? extends JavaScriptModule> jsModuleClass : reactPackage.createJSModules()) {
   jsModulesBuilder.add(jsModuleClass);                    //保存js包 可getModule的时候取出
  }
}

看下core包里是些什么东西。
              ///coreModulesPackage.java
@Override
publicList<NativeModule> createNativeModules(                 //core包的native模块
    ReactApplicationContext catalystApplicationContext) {
  returnArrays.<NativeModule>asList(
      newAnimationsDebugModule(                //调试动画?                        
          catalystApplicationContext,
          mReactInstanceManager.getDevSupportManager().getDevSettings()),
      newAndroidInfoModule(),                    //??
      newDeviceEventManagerModule(catalystApplicationContext,mHardwareBackBtnHandler),   //硬件back键?
      newExceptionsManagerModule(mReactInstanceManager.getDevSupportManager()),  //exception
      newTiming(catalystApplicationContext),      //硬件刷新?
      newSourceCodeModule(                               //??
          mReactInstanceManager.getSourceUrl(),
          mReactInstanceManager.getDevSupportManager().getSourceMapUrl()),
      newUIManagerModule(                                //负责ui的manager
          catalystApplicationContext,
          mReactInstanceManager.createAllViewManagers(catalystApplicationContext)),
      newDebugComponentOwnershipModule(catalystApplicationContext));  //??
}


@Override
publicList<Class<? extendsJavaScriptModule>> createJSModules() {     //core包的js模块
  returnArrays.asList(
      DeviceEventManagerModule.RCTDeviceEventEmitter.class,    
      JSTimersExecution.class,        //js timer?           
      RCTEventEmitter.class,           //js分发touch的emitter?
      AppRegistry.class,                   //具体干啥?
      ReactNative.class,                   //??
      DebugComponentOwnershipModule.RCTDebugComponentOwnership.class);  //调试器
}
                    
看下MainReactPackage包
@Override
publicList<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
  returnArrays.<NativeModule>asList(
    newAsyncStorageModule(reactContext),     //?
    newFrescoModule(reactContext),                //fresco
    newNetworkingModule(reactContext),        //network
    newToastModule(reactContext));               //toast(咦 一个toast有那么重要么
}

@Override
publicList<ViewManager> createViewManagers(ReactApplicationContext reactContext) {  //暴露给js的android控件
  returnArrays.<ViewManager>asList(
    newReactDrawerLayoutManager(),
    newReactHorizontalScrollViewManager(),
    newReactImageManager(),
    newReactProgressBarViewManager(),
    newReactRawTextManager(),
    newReactScrollViewManager(),
    newReactSwitchManager(),
    newReactTextInputManager(),
    newReactTextViewManager(),
    newReactToolbarManager(),
    newReactViewManager(),
    newReactViewPagerManager(),
    newReactVirtualTextViewManager());
}

上面提到经过process后其实已经打通了java和js交互的通道,下面跟踪上篇文章中的一个java调用js代码的runApplication例子来进一步分析具体是怎么实现通信的。
catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams);

public <T extends JavaScriptModule> T getJSModule(Class<T> jsInterface) {        //获取一个js模块
return Assertions.assertNotNull(mJSModuleRegistry).getJavaScriptModule(jsInterface);
public <T extends JavaScriptModule> TgetJavaScriptModule(Class<T> moduleInterface) {                    
  return (T) Assertions.assertNotNull(
     mModuleInstances.get(moduleInterface),///mModuleInstances(hashMap类型 在下面的构造函数中会看到
     "JS module " + moduleInterface.getSimpleName() + " hasn't been registered!");
}    //从这里看出getJSModule函数其实是取出了一个存在mModuleInstance这个map中的某个类 其实就是在上面process后存储的

JavaScriptModuleRegistry.java
public JavaScriptModuleRegistry(
   CatalystInstance instance,
   JavaScriptModulesConfig config) {
  mModuleInstances = new HashMap<>();
  for (JavaScriptModuleRegistration registration : config.getModuleDefinitions()) {
   Class<? extends JavaScriptModule> moduleInterface = registration.getModuleInterface();  //由process过程存储
   JavaScriptModule interfaceProxy =(JavaScriptModule) Proxy.newProxyInstance(  
       moduleInterface.getClassLoader(),
       new Class[]{moduleInterface},
       new JavaScriptModuleInvocationHandler(instance,registration));  //内部类 //这里动态生成的handler是关键-->js require只有一个实体(这样可以确保比如AppRegistry.class实体和js AppRegistry.js一一对应关系
       mModuleInstances.put(moduleInterface, interfaceProxy);     //根据每个接口生成一个对象 并存入map
  }
}  

JavaScriptModuleInvocationHandler
@Override
public @Nullable Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  String tracingName = mModuleRegistration.getTracingName(method);    //mModuleRegistration就是上面的registration
  mCatalystInstance.callFunction(
     mModuleRegistration.getModuleId(),          //根据moduleId和methodId找到正确的函数(这里是AppRegistry.runApplication)
                                                                        //并调用-->下面会看到
     mModuleRegistration.getMethodId(method),
     Arguments.fromJavaArgs(args),
     tracingName);
  return null;
}

CatalystInstance.java
/* package */ void callFunction(
   final int moduleId,
   final int methodId,
final NativeArray arguments,
   final String tracingName) {
  incrementPendingJSCalls();
  mCatalystQueueConfiguration.getJSQueueThread().runOnQueue(
     new Runnable() {
       @Override
       public void run() {
         mCatalystQueueConfiguration.getJSQueueThread().assertIsOnThread();               
           Assertions.assertNotNull(mBridge).callFunction(moduleId, methodId, arguments);   //调用mBridge的callFunction     
       }
     });
}

ReactBridge.java      //看到名字就知道是一个桥梁
private native void initialize(JavaScriptExecutor jsExecutor,
     ReactCallback callback,MessageQueueThread nativeModulesQueueThread);
  public native void loadScriptFromAssets(AssetManager assetManager, String assetName);
  public native void loadScriptFromNetworkCached(String sourceURL, @Nullable String tempFileName);
  public native void callFunction(int moduleId, int methodId, NativeArray arguments);  //native代码 java-->native了
  public native void invokeCallback(int callbackID, NativeArray arguments);
  public native void setGlobalVariable(String propertyName, String jsonEncodedArgument);
  public native boolean supportsProfiling();
  public native void startProfiler(String title);
  public native void stopProfiler(String title, String filename);
}                                      

                 ///////////////后面就转入native调用js代码的过程了 由下面的文章进行分析。



ok~ 这篇文章就先到这里了~
这篇文章分析了ReactContext初始化的过程,可以看到reactContext初始化的时候将java包括native的一些重要
模块注册到了catalyst里,搭起了java js通信的基础。
并跟踪了其中一个runApplication的例子,看到java将moduleId,methodId,args传到了native层,至于native层如何
调用js代码,这篇文章并没有分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值