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 负责模块发现,nativeCallSyncHook 和 nativeFlushQueueImmediate 负责方法调用(同步/异步),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();
}