ReactNative 源码分析1——HybridData 机制深度分析
2026/8/29 19:13:47 网站建设 项目流程

对于想学习Agent开发的朋友可以关注我的新项目:

HelloAgentR工程手记1/100天——项目工作流搭建

一、HybridData 是什么

HybridData来自 Facebook 的fbjni库(com.facebook.jni.HybridData),它是一个将 C++ 对象指针封装在 Java 对象中的桥梁类。本质上是 Java 层持有 C++ 层对象的"句柄",实现了 Java 和 C++ 之间一对一的对象绑定。

二、内存管理流程

┌─────────────────────────────────────────────────┐ │ Java 层 │ │ ┌──────────────────────────────┐ │ │ │ HermesExecutor │ │ │ │ mHybridData ──────────────────┐ │ │ └──────────────────────────────┘ │ │ │ ▼ │ │ ┌──────────────────────────────┐ │ │ │ HybridData (fbjni) │ │ │ │ 内部持有 C++ 指针 (long) │ │ │ └──────────────────────────────┘ │ └─────────────────────────────────────────────────┘ │ JNI ▼ ┌─────────────────────────────────────────────────┐ │ C++ 层 │ │ ┌──────────────────────────────┐ │ │ │ HermesExecutorHolder (C++) │ │ │ │ │ │ │ │ │ │ │ └──────────────────────────────┘ │ └─────────────────────────────────────────────────┘

二、核心工作原理

public class HermesExecutor extends JavaScriptExecutor { private static String mode_ ; static { loadLibrary(); } public static void loadLibrary() throws UnsatisfiedLinkError { if (mode_ == null) { // libhermes must be loaded explicitly to invoke its JNI_OnLoad. SoLoader.loadLibrary( "hermes" ); SoLoader.loadLibrary( "hermes_executor" ); // libhermes_executor is built differently for Debug & Release so we load the proper mode. mode_ = ReactBuildConfig.DEBUG ? "Debug" : "Release" ; } } HermesExecutor(@Nullable RuntimeConfig config, boolean enableDebugger, String debuggerName) { super( config == null ? initHybridDefaultConfig(enableDebugger, debuggerName) : initHybrid(enableDebugger, debuggerName, config.getHeapSizeMB())); } @Override public String getName() { return "HermesExecutor" + mode_ ; } private static native HybridData initHybridDefaultConfig( boolean enableDebugger, String debuggerName); private static native HybridData initHybrid( boolean enableDebugger, String debuggerName, long heapSizeMB); }

HermesExecutor继承JavaScriptExecutor,JavaScriptExecutor中定义了一个mHybridData字段

private final HybridData mHybridData;

HermesExecutor构造函数调用initHybridDefaultConfig或initHybrid返回一个HybridData对象,initHybridDefaultConfig和initHybrid都是native方法;

在OnLoad.cpp中注册了这两个方法,并且这两个方法都是HermesExecutorHolder类中

static void registerNatives() { registerHybrid( {makeNativeMethod( "initHybrid" , HermesExecutorHolder::initHybrid), makeNativeMethod( "initHybridDefaultConfig" , HermesExecutorHolder::initHybridDefaultConfig)}); }

initHybrid中会创建HermesExecutorFactory对象,然后调用makeCxxInstance,它是实现了 Java 和 C++ 之间一对一的对象绑定的关键

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中会创建T对象,在这个案例中T为C++层的HermesExecutorHolder(OnLoad.cpp)

static local_ref<detail::HybridData> makeCxxInstance(Args&&... args) { return makeHybridData( std::unique_ptr<T>(new T(std::forward<Args>(args)...))); }

makeHybridData中创建了一个HybridData对象并返回到Java层

static local_ref<detail::HybridData> makeHybridData( std::unique_ptr<T> cxxPart) { auto hybridData = detail::HybridData::create(); setNativePointer(hybridData, std::move(cxxPart)); return hybridData; }

setNativePointer中t是HybridData对象,new_value是HermesExecutorHolder对象

void setNativePointer( basic_strong_ref<T, Alloc> t, std::unique_ptr<detail::BaseHybridClass> new_value) { getHolder(&*t)->setNativePointer(std::move(new_value)); }

看完getHolder就明白了,它是取出HybridData对象中的mDestructor字段

local_ref<HybridDestructor::javaobject> getHolder(const T* t) { static auto holderField = getDestructorField(t->getClass()); return t->getFieldValue(holderField); } inline JField<HybridDestructor::javaobject> getDestructorField( const local_ref<JClass>& c) { return c->template getField<HybridDestructor::javaobject>( "mDestructor" ); }

setNativePointer最终会将mDestructor.mNativePointer指向HermesExecutorHolder对象

getHolder(&*t)->setNativePointer(std::move(new_value)); 变成 HybridDestructor->setNativePointer(std::move(new_value)); //fbjni-0.7.0/prefab/modules/fbjni/include/fbjni/fbjni.cpp:227-237 void HybridDestructor::setNativePointer( std::unique_ptr<detail::BaseHybridClass> new_value) { static auto pointerField = javaClassStatic()->getField<jlong>("mNativePointer"); auto old_value = std::unique_ptr<detail::BaseHybridClass>( reinterpret_cast<detail::BaseHybridClass*>(getFieldValue(pointerField))); if (new_value && old_value) { FBJNI_LOGF("Attempt to set C++ native pointer twice"); } setFieldValue(pointerField, reinterpret_cast<jlong>(new_value.release())); }

这就是“Java 对象 -> native 指针 -> C++ 实例”的回路。

HermesExecutor (Java++对象) ->HybridData->mDestructor.mNativePointer(指针)->HermesExecutorHolder(C++对象)

四、在 RN 中的应用场景

HybridData 在 React Native 中无处不在,覆盖了几乎所有核心子系统:

子系统Java 类C++ 对应作用
旧架构 BridgeCatalystInstanceImplCatalystInstanceImpl.cpp → InstanceJS 桥的核心实例
新架构 BridgelessReactInstanceJReactInstance.cpp → ReactInstance新架构的运行时实例
JS 引擎HermesExecutor / JSCExecutor对应的 C++ executorJS 执行引擎
JS RuntimeHermesInstance / JSCInstanceC++ runtime factory创建和管理 JS 运行时
数据类型WritableNativeMap / WritableNativeArrayC++ dynamic 对象JS 与 Java 间的数据传递
TurboModuleTurboModuleManagerC++ TurboModule 管理新架构的模块系统
Fabric 渲染ComponentFactoryC++ 组件注册表新架构的渲染系统
运行时工具RuntimeExecutor / RuntimeSchedulerC++ executor/schedulerJS 任务调度

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询