ReactNative 源码分析3——ReactActivity之初始化RN应用

ReactActivity内容逻辑被代理到ReactActivityDelegate,可以看到ReactActivityDelegate中是直接通过ReactApplication获取ReactNativeHost和ReactHost,这点在前面《React Native 源码分析1------Application初始化》文章中已经分析过了

scss 复制代码
protected ReactNativeHost getReactNativeHost() {
  return ((ReactApplication) getPlainActivity().getApplication()).getReactNativeHost();
}

public @Nullable ReactHost getReactHost() {
  return ((ReactApplication) getPlainActivity().getApplication()).getReactHost();
}

看一下onCreate,这里分为新老架构初始化,enableBridgelessArchitecture在ReactApplication初始化时可以进行设置

scss 复制代码
public void onCreate(Bundle savedInstanceState) {
    String mainComponentName = getMainComponentName();
    final Bundle launchOptions = composeLaunchOptions();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isWideColorGamutEnabled()) {
      mActivity.getWindow().setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
    }
    if (ReactNativeFeatureFlags.enableBridgelessArchitecture()) {
      mReactDelegate =
          new ReactDelegate(
              getPlainActivity(), getReactHost(), mainComponentName, launchOptions);
    } else {
      mReactDelegate =
          new ReactDelegate(
              getPlainActivity(),
              getReactNativeHost(),
              mainComponentName,
              launchOptions,
              isFabricEnabled()) {
            @Override
            protected ReactRootView createRootView() {
              ReactRootView rootView = ReactActivityDelegate.this.createRootView();
              if (rootView == null) {
                rootView = super.createRootView();
              }
              return rootView;
            }
          };
    }
    if (mainComponentName != null) {
      loadApp(mainComponentName);
    }
}

这里我们先看enableBridgelessArchitecture=false的场景:

  • 创建ReactDelegate
  • mReactDelegate.loadApp
  • getPlainActivity().setContentView(mReactDelegate.getReactRootView()):设置视图,这里的视图是ReactRootView对象
scss 复制代码
public void loadApp(String appKey) {
  // With Bridgeless enabled, create and start the surface
  if (ReactNativeFeatureFlags.enableBridgelessArchitecture()) {
    if (mReactSurface == null) {
      mReactSurface = mReactHost.createSurface(mActivity, appKey, mLaunchOptions);
    }
    mReactSurface.start();
  } else {
    if (mReactRootView != null) {
      throw new IllegalStateException( "Cannot loadApp while app is already running." );
    }
    mReactRootView = createRootView();
    mReactRootView.startReactApplication(
        getReactNativeHost().getReactInstanceManager(), appKey, mLaunchOptions);
  }
}
  • createRootView:创建ReactRootView
  • ReactInstanceManager创建:这个我们在《React Native 源码分析1------Application初始化》已经讲过了,这里重点讲一下它的创建
  • 调用ReactRootView的startReactApplication

ReactInstanceManager创建

ReactInstanceManagerBuilder.build负责创建

typescript 复制代码
public ReactInstanceManager build() {
  .....
  String appName = mApplication.getPackageName();
  String deviceName = AndroidInfoHelpers.getFriendlyDeviceName();

  return new ReactInstanceManager(
      mApplication,
      mCurrentActivity,
      mDefaultHardwareBackBtnHandler,
      mJavaScriptExecutorFactory == null
          ? getDefaultJSExecutorFactory(appName, deviceName, mApplication.getApplicationContext())
          : mJavaScriptExecutorFactory,
      (mJSBundleLoader == null && mJSBundleAssetUrl != null)
          ? JSBundleLoader.createAssetLoader(
              mApplication, mJSBundleAssetUrl, false /*Asynchronous*/)
          : mJSBundleLoader,
          ....
      );
}

mJSBundleLoader

  • JSBundleLoader.createAssetLoader:从Asset加载JS文件
  • JSBundleLoader.createFileLoader:从file加载JS文件

getDefaultJSExecutorFactory很重要,它创建不同的JS引擎:

  • HermesExecutorFactory:facebook官方自己构建的JS引擎,专门针对RN移动端进行优化的
  • JSCExecutorFactory:JavaScriptCore,WebKit内核浏览器

mJSEngineResolutionAlgorithm在ReactApplication初始化时可以进行配置

kotlin 复制代码
override val reactNativeHost: ReactNativeHost =
    object : DefaultReactNativeHost(this) {
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}

 private JavaScriptExecutorFactory getDefaultJSExecutorFactory(
      String appName, String deviceName, Context applicationContext) {

    initializeSoLoaderIfNecessary(applicationContext);
    // Hermes has been enabled by default in OSS since React Native 0.70.
    // If the user hasn't specified a JSEngineResolutionAlgorithm,
    // we attempt to load Hermes first, and fallback to JSC if we can't resolve the library.
    if (mJSEngineResolutionAlgorithm == null) {
      try {
        HermesExecutor.loadLibrary();
        return new HermesExecutorFactory();
      } catch (UnsatisfiedLinkError ignoredHermesError) {
        try {
          JSCExecutor.loadLibrary();
          return new JSCExecutorFactory(appName, deviceName);
        } catch (UnsatisfiedLinkError jscError) {
          FLog.e(
              TAG,
              "Unable to load neither the Hermes nor the JSC native library. "
+ "Your application is not built correctly and will fail to execute" );
          if (jscError.getMessage().contains( "__cxa_bad_typeid" )) {
            throw jscError;
          }
          return null;
        }
      }
    } else if (mJSEngineResolutionAlgorithm == JSEngineResolutionAlgorithm.HERMES) {
      HermesExecutor.loadLibrary();
      return new HermesExecutorFactory();
    } else {
      JSCExecutor.loadLibrary();
      return new JSCExecutorFactory(appName, deviceName);
    }
  }
}

ReactInstanceManager构造函数

  • CoreModulesPackage:RN内部模块,非常重要后面我们分析Native View创建流程会分析到
  • DebugCorePackage:开发调试阶段使用
  • packages:这是开发者外部自定义的module,就是ReactApplication初始化时传入的
  • ReactChoreographer:RN内部控制UI绘制的编舞者初始化
less 复制代码
  mPackages.add(
      new CoreModulesPackage(
          this,
          new DefaultHardwareBackBtnHandler() {
            @Override
            public void invokeDefaultOnBackPressed() {
              ReactInstanceManager.this.invokeDefaultOnBackPressed();
            }
          },
          lazyViewManagersEnabled,
          minTimeLeftInFrameForNonBatchedOperationMs));
  if (mUseDeveloperSupport) {
    mPackages.add(new DebugCorePackage());
  }
  mPackages.addAll(packages);
}
mUIManagerProvider = uIManagerProvider;

// Instantiate ReactChoreographer in UI thread.
ReactChoreographer.initialize(
    choreographerProvider != null
        ? choreographerProvider
        : AndroidChoreographerProvider.getInstance());
kotlin 复制代码
class MainApplication : Application(), ReactApplication {
  override val reactNativeHost: ReactNativeHost =
      object : DefaultReactNativeHost(this) {
        override fun getPackages(): List<ReactPackage> =
            PackageList(this).packages.apply  {
               add(MyReactNativePackage())
            }
            
            ....
}
}

到此ReactInstanceManager创建完成,我们继续回到ReactRootView.startReactApplication

启动后台线程

继续往下面看,这里构造了ReactContextInitParams,参数前面也分析了的

ini 复制代码
private void recreateReactContextInBackground(
    JavaScriptExecutorFactory jsExecutorFactory, JSBundleLoader jsBundleLoader) {
  FLog.d(ReactConstants.TAG, "ReactInstanceManager.recreateReactContextInBackground()" );
  UiThreadUtil.assertOnUiThread();

  final ReactContextInitParams initParams =
      new ReactContextInitParams(jsExecutorFactory, jsBundleLoader);
  if (mCreateReactContextThread == null) {
    runCreateReactContextOnNewThread(initParams);
  } else {
    mPendingReactContextInitParams = initParams;
  }
}

runCreateReactContextOnNewThread启动一个线程进行初始化,核心的 2 个方法

  • createReactContext:负责RN应用初始化,包含 3 大线程、C++层、JS和Native通信
  • setupReactContext:负责启动RN应用
ini 复制代码
private void runCreateReactContextOnNewThread(final ReactContextInitParams initParams) {


  mCreateReactContextThread =
      new Thread(
          null,
          () -> {
            final ReactApplicationContext reactApplicationContext;
            try {
              Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
              ReactMarker.logMarker(VM_INIT);
              reactApplicationContext =
                  createReactContext(
                      initParams.getJsExecutorFactory().create(), initParams.getJsBundleLoader());
            } catch (Exception e) {
              // Reset state and bail out. This lets us try again later.
              mHasStartedCreatingInitialContext = false;
              mCreateReactContextThread = null;
              mDevSupportManager.handleException(e);
              return;
            }
            ....
            try {
              ...
              Runnable setupReactContextRunnable =
                  () -> {
                    try {
                      setupReactContext(reactApplicationContext);
                    } catch (Exception e) {
                      mDevSupportManager.handleException(e);
                    }
                  };

              reactApplicationContext.runOnNativeModulesQueueThread(setupReactContextRunnable);
            } catch (Exception e) {
              mDevSupportManager.handleException(e);
            }
          },
          "create_react_context" );
  mCreateReactContextThread.start();
}

在调用createReactContext前调用了,这里的JsExecutorFactory就是HermesExecutorFactory或JSCExecutorFactory

scss 复制代码
initParams.getJsExecutorFactory().create()

我们以HermesExecutorFactory为例进行分析

less 复制代码
@Override
public JavaScriptExecutor create() {
  return new HermesExecutor(mConfig, mEnableDebugger, mDebuggerName);
}

HermesExecutor(@Nullable RuntimeConfig config, boolean enableDebugger, String debuggerName) {
  super(
      config == null
          ? initHybridDefaultConfig(enableDebugger, debuggerName)
          : initHybrid(enableDebugger, debuggerName, config.getHeapSizeMB()));
}

这里创建HermesExecutor,然后调用到native方法initHybrid,HermesExecutor继承JavaScriptExecutor它里面有HybridData 这里看《HybridData 机制深度分析》就能知道它是做什么的了。

createReactContext

createReactContext方法主要功能:

  • 创建并初始化BridgeReactContext
  • NativeModuleRegistry中统一管理所有module
  • 创建CatalystInstanceImpl,它主要是构建Native和JS通信
  • 调用reactContext.initializeWithInstance进行初始化

NativeModule管理

这里循环处理mPackages,然后返回NativeModuleRegistry

ini 复制代码
private NativeModuleRegistry processPackages(
    ReactApplicationContext reactContext, List<ReactPackage> packages) {
  NativeModuleRegistryBuilder nativeModuleRegistryBuilder =
      new NativeModuleRegistryBuilder(reactContext);

  synchronized (mPackages) {
    for (ReactPackage reactPackage : packages) {
      Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "createAndProcessCustomReactPackage" );
      try {
        processPackage(reactPackage, nativeModuleRegistryBuilder);
      } finally {
        Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
      }
    }
  }

  NativeModuleRegistry nativeModuleRegistry;
  try {
    nativeModuleRegistry = nativeModuleRegistryBuilder.build();
  } finally {
  }

  return nativeModuleRegistry;
}

processPackage中调用getNativeModuleIterator

scss 复制代码
reactPackage.getNativeModuleIterator(reactApplicationContext)

getNativeModuleIterator中返回ModuleHolder对象,ModuleHolder构造函数中传入 2 个参数

  • ReactModuleInfo:这个就是我们自定义的module以及RN内置的module
  • ModuleHolderProvider:保存了module名称和ReactApplicationContext对象
scss 复制代码
ModuleHolder(entry.value, ModuleHolderProvider(entry.key, reactContext))

最后将ModuleHolder再构造成一个HashMap<String, ModuleHolder>对象

python 复制代码
    for (moduleHolder in moduleHolders) {
      val name = moduleHolder.name
val existingNativeModule = modules[name]
      if (existingNativeModule != null) {
        check(moduleHolder.canOverrideExistingModule) {
 """
Native module $name tried to override ${existingNativeModule.className} .

Check the getPackages() method in MainApplication.java, it might be that module is being created twice.
If this was your intention, set canOverrideExistingModule=true. This error may also be present if the
package is present only once in getPackages() but is also automatically added later during build time
by autolinking. Try removing the existing entry and rebuild.
"""
}
}
      modules[name] = moduleHolder
    }

最后调用build创建出NativeModuleRegistry,它里面持有了:

  • ReactApplicationContext
  • Map<String, ModuleHolder> modules
ini 复制代码
nativeModuleRegistry = nativeModuleRegistryBuilder.build();

CatalystInstanceImpl创建

scss 复制代码
CatalystInstanceImpl.Builder catalystInstanceBuilder =
    new CatalystInstanceImpl.Builder()
        .setReactQueueConfigurationSpec(ReactQueueConfigurationSpec.createDefault())
        .setJSExecutor(jsExecutor)
        .setRegistry(nativeModuleRegistry)
        .setJSBundleLoader(jsBundleLoader)
        .setJSExceptionHandler(exceptionHandler)
        .setInspectorTarget(getOrCreateInspectorTarget());

catalystInstance = catalystInstanceBuilder.build();

这里创建native_modules和js线程的规格,这两个线程的类型都是ThreadType.NEW_BACKGROUND

  • native_modules线程:客户端所有的module都运行在此线程
  • js线程:js运行的线程
scss 复制代码
ReactQueueConfigurationSpec.createDefault()

CatalystInstanceImpl构造函数非常重要,核心做了几件事:

  • initHybrid:初始化C++层
  • ReactQueueConfigurationImpl.create创建RN的 3 大线程:native_modules线程、js线程、UI线程
  • initializeBridge:建立Native和Js通信桥梁
  • JavaScriptModuleRegistry:用于Native调用JS
ini 复制代码
private CatalystInstanceImpl(
    final ReactQueueConfigurationSpec reactQueueConfigurationSpec,
    final JavaScriptExecutor jsExecutor,
    final NativeModuleRegistry nativeModuleRegistry,
    final JSBundleLoader jsBundleLoader,
    JSExceptionHandler jSExceptionHandler,
    @Nullable ReactInstanceManagerInspectorTarget inspectorTarget) {
  mHybridData = initHybrid();

  mReactQueueConfiguration =
      ReactQueueConfigurationImpl.create(
          reactQueueConfigurationSpec, new NativeExceptionHandler());
  mBridgeIdleListeners = new CopyOnWriteArrayList<>();
  mNativeModuleRegistry = nativeModuleRegistry;
  mJSModuleRegistry = new JavaScriptModuleRegistry();
  mJSBundleLoader = jsBundleLoader;
  mJSExceptionHandler = jSExceptionHandler;
  mNativeModulesQueueThread = mReactQueueConfiguration.getNativeModulesQueueThread();

  initializeBridge(
      new InstanceCallback(this),
      jsExecutor,
      mReactQueueConfiguration.getJSQueueThread(),
      mNativeModulesQueueThread,
      mNativeModuleRegistry.getJavaModules(this),
      mNativeModuleRegistry.getCxxModules(),
      mInspectorTarget);

  mJavaScriptContextHolder = new JavaScriptContextHolder(getJavaScriptContext());
}

initHybrid

initHybrid是native方法,它的C++实现在CatalystInstanceImpl.cpp,它返回的也是一个HybridData对象,通过将Java的CatalystInstanceImpl和C++层的CatalystInstanceImpl进行绑定

csharp 复制代码
private static native HybridData initHybrid();

三大线程创建

create中创建三大线程,然后再ReactQueueConfigurationImpl中统一管理

ini 复制代码
public static ReactQueueConfigurationImpl create(
    ReactQueueConfigurationSpec spec, QueueThreadExceptionHandler exceptionHandler) {
  MessageQueueThreadImpl uiThread =
      MessageQueueThreadImpl.create(MessageQueueThreadSpec.mainThreadSpec(), exceptionHandler);
  MessageQueueThreadImpl jsThread =
      MessageQueueThreadImpl.create(spec.getJSQueueThreadSpec(), exceptionHandler);
  MessageQueueThreadImpl nativeModulesThread =
      MessageQueueThreadImpl.create(spec.getNativeModulesQueueThreadSpec(), exceptionHandler);
  return new ReactQueueConfigurationImpl(uiThread, nativeModulesThread, jsThread);
}

每个线程对应一个MessageQueueThreadImpl的实现,其实就是Handler+Looper机制

ini 复制代码
private MessageQueueThreadImpl(
    String name,
    Looper looper,
    QueueThreadExceptionHandler exceptionHandler,
    @Nullable MessageQueueThreadPerfStats stats) {
  mName = name;
  mLooper = looper;
  mHandler = new MessageQueueThreadHandler(looper, exceptionHandler);
  mPerfStats = stats;
  mAssertionErrorMessage = "Expected to be called from the '" + getName() + "' thread!" ;
}

后续可以调用MessageQueueThreadImpl如下方法在对应线程运行

java 复制代码
public boolean runOnQueue(Runnable runnable) 

boolean runOnQueue(Runnable runnable);

initializeBridge(C++层)

CatalystInstanceImpl的构造函数创建了一个Instance实例(Instance.cpp)

css 复制代码
CatalystInstanceImpl::CatalystInstanceImpl()
    : instance_(std::make_unique<Instance>()) {}

initializeBridge构造函数传入了如下几个重要参数:

  • InstanceCallback:用于C++层将状态信息同步到Java层
  • jsExecutor:HermesExecutor或JSCExecutor,前面讲过了
  • getJSQueueThread:JS线程
  • mNativeModulesQueueThread:NativeModules线程,通俗点将就是开发者自定义的API
  • getJavaModules:Java模块
  • getCxxModules:C++模块
scss 复制代码
initializeBridge(
    new InstanceCallback(this),
    jsExecutor,
    mReactQueueConfiguration.getJSQueueThread(),
    mNativeModulesQueueThread,
    mNativeModuleRegistry.getJavaModules(this),
    mNativeModuleRegistry.getCxxModules(),
    mInspectorTarget);

我们看看c++层的实现

ruby 复制代码
void CatalystInstanceImpl::initializeBridge(
    jni::alias_ref<JInstanceCallback::javaobject> callback,
    // This executor is actually a factory holder.
    JavaScriptExecutorHolder* jseh,
    jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,
    jni::alias_ref<JavaMessageQueueThread::javaobject> nativeModulesQueue,
    jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject>
        javaModules,
    jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject>
        cxxModules,
    jni::alias_ref<ReactInstanceManagerInspectorTarget::javaobject>
        inspectorTarget) {
  set_react_native_logfunc(&log);
  
  moduleMessageQueue_ =
      std::make_shared<JMessageQueueThread>(nativeModulesQueue);

  moduleRegistry_ = std::make_shared<ModuleRegistry>(buildNativeModuleList(
      std::weak_ptr<Instance>(instance_),
      javaModules,
      cxxModules,
      moduleMessageQueue_));

  instance_->initializeBridge(
      std::make_unique<InstanceCallbackImpl>(callback),
      jseh->getExecutorFactory(),
      std::make_unique<JMessageQueueThread>(jsQueue),
      moduleRegistry_,
      inspectorTarget != nullptr
          ? inspectorTarget->cthis()->getInspectorTarget()
          : nullptr);
}

我们先看看的完整语法

ini 复制代码
moduleMessageQueue_ = std::make_shared<JMessageQueueThread>(nativeModulesQueue);
  • moduleMessageQueue_:类型是std::shared_ptr,指向 JMessageQueueThread智能指针 ,自动管理引用计数,多个 shared_ptr 可共享同一对象的所有权,最后一个持有者销毁时自动释放内存

  • std::make_shared(args...):在堆上分配 T 对象并返回 shared_ptr<T>

所以这里其实就是创建C++层的JMessageQueueThread(JMessageQueueThread.cpp)对象,然后m_jobj持有Java层的JavaMessageQueueThread对象

css 复制代码
JMessageQueueThread::JMessageQueueThread(
    alias_ref<JavaMessageQueueThread::javaobject> jobj)
    : m_jobj(make_global(jobj)) {}

它的作用是让Java、C++关于nativeModules的调用都在同一个线程,试想一下为什么要从Java层传递到C++?因为跨平台的问题,IOS也需要创建属于自己平台的线程队列,然后传递到C++层。后续C++层可以调用如下方法将任务分发到Java的线程队列中执行

scss 复制代码
void JMessageQueueThread::runOnQueue(std::function<void()>&& runnable) {
  jni::ThreadScope guard;
  //找到Java层对应的runOnQueue方法
  static auto method =
      JavaMessageQueueThread::javaClassStatic()
          ->getMethod<jboolean(JRunnable::javaobject)>( "runOnQueue" );
  auto jrunnable =
      JNativeRunnable::newObjectCxxArgs(wrapRunnable(std::move(runnable)));
  //在m_jobj对象上执行runOnQueue方法,m_jobj是JavaMessageQueueThread对象    
  method(m_jobj, jrunnable.get());
}

所以最后调用的是JavaMessageQueueThread.runOnQueue,在"三大线程创建"我们已经讲过JavaMessageQueueThread了。

C++对Java层NativeModule调用

我们继续看buildNativeModuleList方法(ModuleRegistryBuilder.cpp)

c 复制代码
std::vector<std::unique_ptr<NativeModule>> buildNativeModuleList(
    std::weak_ptr<Instance> winstance,
    jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject>
        javaModules,
    jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject>
        cxxModules,
    std::shared_ptr<MessageQueueThread> moduleMessageQueue) {
  std::vector<std::unique_ptr<NativeModule>> modules;
  if (javaModules) {
    for (const auto& jm : *javaModules) {
      modules.emplace_back(std::make_unique<JavaNativeModule>(
          winstance, jm, moduleMessageQueue));
    }
  }
  if (cxxModules) {
    for (const auto& cm : *cxxModules) {
      std::string moduleName = cm->getName();
      modules.emplace_back(std::make_unique<CxxNativeModule>(
          winstance,
          moduleName,
          cm->getProvider(moduleName),
          moduleMessageQueue));
    }
  }
  return modules;
}

我们重点分析下面这部分大家就能明白了

arduino 复制代码
for (const auto& jm : *javaModules) {
  modules.emplace_back(std::make_unique<JavaNativeModule>(
      winstance, jm, moduleMessageQueue));
}

这里构造JavaNativeModule对象,每个对象中包含:

  • C++层的instance_实例
  • wrapper_指向Java层的JavaModuleWrapper,表示一个Java层module
  • messageQueueThread_:Java层传递到C++层的线程
ruby 复制代码
class JavaNativeModule : public NativeModule {
 public:
  JavaNativeModule(
      std::weak_ptr<Instance> instance,
      jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
      std::shared_ptr<MessageQueueThread> messageQueueThread)
      : instance_(std::move(instance)),
        wrapper_(make_global(wrapper)),
        messageQueueThread_(std::move(messageQueueThread)) {}
        
}

后续当C++层需要调用Java层module时就可以通过wrapper_调用到

scss 复制代码
//JavaModuleWrapper.cpp
void JavaNativeModule::invoke(
    unsigned int reactMethodId,
    folly::dynamic&& params,
    int callId) {
  messageQueueThread_->runOnQueue(
      [this, reactMethodId, params = std::move(params), callId] {
        static auto invokeMethod =
            wrapper_->getClass()
                ->getMethod<void(jint, ReadableNativeArray::javaobject)>(
                    "invoke" );
#ifdef WITH_FBSYSTRACE
        if (callId != -1) {
          fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native" , callId);
        }
#endif
        invokeMethod(
            wrapper_,
            static_cast<jint>(reactMethodId),
            ReadableNativeArray::newObjectCxxArgs(std::move(params)).get());
      });
}
  • 先获取到JavaModuleWrapper中的invoke方法
  • 然后调用invokeMethod执行

到这里其实就完成了C++持有Java对象并进行调用的整个链路了。

arduino 复制代码
class JavaModuleWrapper {
    @DoNotStrip
    public void invoke(int methodId, ReadableNativeArray parameters) {
      if (methodId >= mMethods.size()) {
        return;
      }
    
      mMethods.get(methodId).invoke(mJSInstance, parameters);
    }
}

回到buildNativeModuleList方法的本质

  • 创建了C++层的ModuleRegistry持有Java层的NativeModules
  • 并在C++层的JavaNativeModule封装了一系列回调Java层的方法
  • 所有回调Java层的都发生在NativeModules线程
jseh->getExecutorFactory

在《HybridData 机制深度分析》一文中我们讲过

scss 复制代码
HermesExecutor (Java++对象) ->HybridData->mDestructor.mNativePointer(指针)->HermesExecutorHolder(C++对象) 

所以这里的jseh就是HermesExecutorHolder对象

arduino 复制代码
class JavaScriptExecutorHolder
    : public jni::HybridClass<JavaScriptExecutorHolder> {
 public:
  static constexpr auto kJavaDescriptor =
      "Lcom/facebook/react/bridge/JavaScriptExecutor;" ;

  std::shared_ptr<JSExecutorFactory> getExecutorFactory() {
    return mExecutorFactory;
  }

 protected:
  JavaScriptExecutorHolder(std::shared_ptr<JSExecutorFactory> factory)
      : mExecutorFactory(factory) {}

 private:
  std::shared_ptr<JSExecutorFactory> mExecutorFactory;
};

} // namespace facebook::react

getExecutorFactory返回mExecutorFactory,它是在构造函数中初始化的,我们看看它是在哪里被构造的

rust 复制代码
//OnLoad.cpp
static jni::local_ref<jhybriddata> initHybrid(
    jni::alias_ref<jclass>,
    bool enableDebugger,
    std::string debuggerName,
    jlong heapSizeMB) {
  JReactMarker::setLogPerfMarkerIfNeeded();
  auto runtimeConfig = makeRuntimeConfig(heapSizeMB);
  std::call_once(flag, []() {
    facebook::hermes::HermesRuntime::setFatalHandler(hermesFatalHandler);
  });
  auto factory = std::make_unique<HermesExecutorFactory>(
      installBindings, JSIExecutor::defaultTimeoutInvoker, runtimeConfig);
  factory->setEnableDebugger(enableDebugger);
  if (!debuggerName.empty()) {
    factory->setDebuggerName(debuggerName);
  }
  return makeCxxInstance(std::move(factory));
}

在makeCxxInstance中被创建,传入了factory,它其实就是HermesExecutorFactory

Instance::initializeBridge

  • InstanceCallback:用于C++层将状态信息同步到Java层
  • jsef:HermesExecutorFactory(HermesExecutorFactory.cpp)
  • jsQueue:JS运行线程
  • moduleRegistry:NativeModule管理器,它里面已经包含了NativeModules线程,所有JS对NativeModules的调用都发生在此线程上
ini 复制代码
void Instance::initializeBridge(
    std::unique_ptr<InstanceCallback> callback,
    std::shared_ptr<JSExecutorFactory> jsef,
    std::shared_ptr<MessageQueueThread> jsQueue,
    std::shared_ptr<ModuleRegistry> moduleRegistry,
    jsinspector_modern::HostTarget* parentInspectorTarget) {
  callback_ = std::move(callback);
  moduleRegistry_ = std::move(moduleRegistry);
  parentInspectorTarget_ = parentInspectorTarget;

  jsQueue->runOnQueueSync([this, &jsef, jsQueue]() mutable {
    nativeToJsBridge_ = std::make_shared<NativeToJsBridge>(
        jsef.get(), moduleRegistry_, jsQueue, callback_);

    if (parentInspectorTarget_ != nullptr) {
      auto inspectorExecutor = parentInspectorTarget_->executorFromThis();
      std::mutex inspectorInitializedMutex;
      std::condition_variable inspectorInitializedCv;
      bool inspectorInitialized = false;

      inspectorExecutor([this,
                         &inspectorInitialized,
                         &inspectorInitializedMutex,
                         &inspectorInitializedCv](
                            jsinspector_modern::HostTarget& hostTarget) {
        inspectorTarget_ = &hostTarget.registerInstance(*this);
        RuntimeExecutor runtimeExecutorIfJsi = getRuntimeExecutor();
        runtimeInspectorTarget_ = &inspectorTarget_->registerRuntime(
            nativeToJsBridge_->getInspectorTargetDelegate(),
            runtimeExecutorIfJsi ? runtimeExecutorIfJsi : [](auto) {});

        // Signal that initialization is complete
        {
          std::lock_guard lock(inspectorInitializedMutex);
          inspectorInitialized = true;
        }
        inspectorInitializedCv.notify_one();
      });

      // Wait for the initialization work to complete
      {
        std::unique_lock lock(inspectorInitializedMutex);
        inspectorInitializedCv.wait(
            lock, [&inspectorInitialized] { return inspectorInitialized; });
      }
    }

    // Initialize the JavaScript runtime after we've initialized the inspector
    nativeToJsBridge_->initializeRuntime();

    jsCallInvoker_->setNativeToJsBridgeAndFlushCalls(nativeToJsBridge_);

    std::scoped_lock lock(m_syncMutex);
    m_syncReady = true;
    m_syncCV.notify_all();
  });
}
  • jsQueue->runOnQueueSync:在Js线程中执行
  • 创建NativeToJsBridge
  • nativeToJsBridge_->initializeRuntime:初始化NativeToJsBridge

我们先看NativeToJsBridge的构造函数

  • m_delegate = JsToNativeBridge对象
  • m_executorMessageQueueThread:JS线程
  • jsExecutorFactory是HermesExecutorFactory
c 复制代码
NativeToJsBridge::NativeToJsBridge(
    JSExecutorFactory* jsExecutorFactory,
    std::shared_ptr<ModuleRegistry> registry,
    std::shared_ptr<MessageQueueThread> jsQueue,
    std::shared_ptr<InstanceCallback> callback)
    : m_destroyed(std::make_shared<bool>(false)),
      m_delegate(std::make_shared<JsToNativeBridge>(registry, callback)),
      m_executor(jsExecutorFactory->createJSExecutor(m_delegate, jsQueue)),
      m_executorMessageQueueThread(std::move(jsQueue)),
      m_inspectable(m_executor->isInspectable()) {}

createJSExecutor返回HermesExecutor对象,因此m_executor = new HermesExecutor()

c 复制代码
std::unique_ptr<JSExecutor> HermesExecutorFactory::createJSExecutor(
    std::shared_ptr<ExecutorDelegate> delegate,
    std::shared_ptr<MessageQueueThread> jsQueue) {
    
    std::unique_ptr<HermesRuntime> hermesRuntime;
    {
      SystraceSection s( "makeHermesRuntime" );
      hermesRuntime = hermes::makeHermesRuntime(runtimeConfig_);
    }
    
    auto decoratedRuntime = std::make_shared<DecoratedRuntime>(
    std::move(hermesRuntime),
    hermesRuntimeRef,
    jsQueue,
    enableDebugger,
    debuggerName_);
  
    return std::make_unique<HermesExecutor>(
      decoratedRuntime,
      delegate,
      jsQueue,
      timeoutInvoker_,
      runtimeInstaller_,
      hermesRuntimeRef);
}

再看看HermesExecutor的构造函数

  • delegate:JsToNativeBridge对象
  • runtime_:DecoratedRuntime对象,它里面包装了HermesRuntime运行时
c 复制代码
//HermesExecutorFactory.cpp
HermesExecutor::HermesExecutor(
    std::shared_ptr<jsi::Runtime> runtime,
    std::shared_ptr<ExecutorDelegate> delegate,
    std::shared_ptr<MessageQueueThread> jsQueue,
    const JSIScopedTimeoutInvoker& timeoutInvoker,
    RuntimeInstaller runtimeInstaller,
    HermesRuntime& hermesRuntime)
    : JSIExecutor(runtime, delegate, timeoutInvoker, runtimeInstaller),
      runtime_(runtime),
      hermesRuntime_(runtime_, &hermesRuntime) {}

看看JSIExecutor构造函数

  • delegate_:JsToNativeBridge对象
  • nativeModules_:JSINativeModules对象,里面包含ModuleRegistry对象
  • moduleRegistry_:ModuleRegistry对象
scss 复制代码
JSIExecutor::JSIExecutor(
    std::shared_ptr<jsi::Runtime> runtime,
    std::shared_ptr<ExecutorDelegate> delegate,
    const JSIScopedTimeoutInvoker& scopedTimeoutInvoker,
    RuntimeInstaller runtimeInstaller)
    : runtime_(runtime),
      delegate_(delegate),
      nativeModules_(std::make_shared<JSINativeModules>(
          delegate ? delegate->getModuleRegistry() : nullptr)),
      moduleRegistry_(delegate ? delegate->getModuleRegistry() : nullptr),
      scopedTimeoutInvoker_(scopedTimeoutInvoker),
      runtimeInstaller_(runtimeInstaller) {
  runtime_->global().setProperty(
      *runtime, "__jsiExecutorDescription" , runtime->description());
}

继续看nativeToJsBridge_->initializeRuntime初始化

scss 复制代码
void NativeToJsBridge::initializeRuntime() {
  runOnExecutorQueue(
      [](JSExecutor* executor) mutable { executor->initializeRuntime(); });
}

executor其实就是NativeToJsBridge构造函数中的m_executor = new HermesExecutor(),也就是会调用HermesExecutor.initializeRuntime,HermesExecutor自身没有实现initializeRuntime方法,所以调用的是其子类JSIExecutor的方法

rust 复制代码
//JSIExecutor.cpp
void JSIExecutor::initializeRuntime() {
  runtime_->global().setProperty(
      *runtime_,
      "nativeModuleProxy" ,
      Object::createFromHostObject(
          *runtime_, std::make_shared<NativeModuleProxy>(nativeModules_)));

  runtime_->global().setProperty(
      *runtime_,
      "nativeFlushQueueImmediate" ,
      Function::createFromHostFunction(
          *runtime_,
          PropNameID::forAscii(*runtime_, "nativeFlushQueueImmediate" ),
          1,
          [this](
              jsi::Runtime&,
              const jsi::Value&,
              const jsi::Value* args,
              size_t count) {
            if (count != 1) {
              throw std::invalid_argument(
                  "nativeFlushQueueImmediate arg count must be 1" );
            }
            callNativeModules(args[0], false);
            return Value::undefined();
          }));

  runtime_->global().setProperty(
      *runtime_,
      "nativeCallSyncHook" ,
      Function::createFromHostFunction(
          *runtime_,
          PropNameID::forAscii(*runtime_, "nativeCallSyncHook" ),
          1,
          [this](
              jsi::Runtime&,
              const jsi::Value&,
              const jsi::Value* args,
              size_t count) { return nativeCallSyncHook(args, count); }));

  runtime_->global().setProperty(
      *runtime_,
      "globalEvalWithSourceUrl" ,
      Function::createFromHostFunction(
          *runtime_,
          PropNameID::forAscii(*runtime_, "globalEvalWithSourceUrl" ),
          1,
          [this](
              jsi::Runtime&,
              const jsi::Value&,
              const jsi::Value* args,
              size_t count) { return globalEvalWithSourceUrl(args, count); }));
}

这四个注册项构成了 JS ↔ Native 通信的核心桥梁nativeModuleProxy 负责模块发现,nativeCallSyncHooknativeFlushQueueImmediate 负责方法调用(同步/异步),globalEvalWithSourceUrl 负责代码动态加载。

全局名称 类型 核心功能
nativeModuleProxy HostObject JS 访问所有 Native Module 的代理对象
nativeFlushQueueImmediate Function(1 arg) 立即执行积压的原生方法调用队列
nativeCallSyncHook Function(3 args) 同步调用指定原生模块的方法并获取返回值
globalEvalWithSourceUrl Function(1-2 args) 带 source URL 动态执行 JS 代码

BridgeReactContext初始化

BridgeReactContext初始化比较简单

  • 持有CatalystInstance实例
  • 持有三大线程:mUiMessageQueueThread、mNativeModulesMessageQueueThread、mJSMessageQueueThread
scss 复制代码
//ReactInstanceManager.createReactContext
reactContext.initializeWithInstance(catalystInstance);


public void initializeWithInstance(CatalystInstance catalystInstance) {
  if (catalystInstance == null) {
    throw new IllegalArgumentException( "CatalystInstance cannot be null." );
  }
  if (mCatalystInstance != null) {
    throw new IllegalStateException( "ReactContext has been already initialized" );
  }
  if (mDestroyed) {
    ReactSoftExceptionLogger.logSoftException(
        TAG,
        new IllegalStateException( "Cannot initialize ReactContext after it has been destroyed." ));
  }

  mCatalystInstance = catalystInstance;

  ReactQueueConfiguration queueConfig = catalystInstance.getReactQueueConfiguration();
  initializeMessageQueueThreads(queueConfig);
  initializeInteropModules();
}
相关推荐
YaBingSec2 小时前
网络安全靶场WP:Grafana 任意文件读取漏洞(CVE-2021-43798)
android·笔记·安全·web安全·ssh·grafana
YF02112 小时前
彻底解决Android非SDK接口绕过限制的深度实践
android·google·app
IVEN_2 小时前
Gradle 依赖下载 403 Forbidden 修复:全局镜像配置实战
android·后端
恋猫de小郭3 小时前
Flutter 3.44 发布前夕,官方宣布 SwiftPM 将完全取代 CocoaPods
android·前端·flutter
黄林晴3 小时前
重磅发布!KMP 双端订阅支付彻底封神,一套代码搞定 iOS+Android
android·kotlin
一个扣子3 小时前
Hermes 未来路线图:2025 年起的新特性与 React Native New Architecture 协同
react native·未来发展·路线图·hermes·字节码diffing·性能增强
Carson带你学Android3 小时前
别再乱学了!深度解读 Google 官方发布 Android 6 大核心 Skills
android·前端·ai编程
张风捷特烈3 小时前
状态管理大乱斗#06 | Riverpod 源码评析 (下) - 外功心法
android·前端·flutter
三少爷的鞋4 小时前
Kotlin 协程 vs Java 虚拟线程:两种并发模型的对比
android