React Native 源码分析1——HybridData 机制深度分析

基于RN0.77 源码

一、HybridData 是什么

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

二、内存管理流程

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

二、核心工作原理

java 复制代码
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字段

arduino 复制代码
private final HybridData mHybridData;

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

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

scss 复制代码
static void registerNatives() {
  registerHybrid(
      {makeNativeMethod( "initHybrid" , HermesExecutorHolder::initHybrid),
       makeNativeMethod(
           "initHybridDefaultConfig" ,
           HermesExecutorHolder::initHybridDefaultConfig)});
}

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

rust 复制代码
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)

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

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

c 复制代码
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对象

scss 复制代码
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字段

rust 复制代码
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对象

scss 复制代码
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++ 实例"的回路。

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

四、在 RN 中的应用场景

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

子系统 Java 类 C++ 对应 作用
旧架构 Bridge CatalystInstanceImpl CatalystInstanceImpl.cpp → Instance JS 桥的核心实例
新架构 Bridgeless ReactInstance JReactInstance.cpp → ReactInstance 新架构的运行时实例
JS 引擎 HermesExecutor / JSCExecutor 对应的 C++ executor JS 执行引擎
JS Runtime HermesInstance / JSCInstance C++ runtime factory 创建和管理 JS 运行时
数据类型 WritableNativeMap / WritableNativeArray C++ dynamic 对象 JS 与 Java 间的数据传递
TurboModule TurboModuleManager C++ TurboModule 管理 新架构的模块系统
Fabric 渲染 ComponentFactory C++ 组件注册表 新架构的渲染系统
运行时工具 RuntimeExecutor / RuntimeScheduler C++ executor/scheduler JS 任务调度
相关推荐
空中海1 小时前
01 React Native 基础、核心组件与布局体系
javascript·react native·react.js
程序员陆业聪2 小时前
跨平台框架全景图:Flutter/KMP/KuiKly/RN的2026年格局
android
码云数智-园园3 小时前
Fibers(纤程)来了:打破阻塞,实现纯PHP下的异步非阻塞IO
android
Yue1684 小时前
一文教你五分钟学会Zustand,React状态管理更加方便!
react native
空中海4 小时前
03 性能、动画与 React Native 新架构
react native·react.js·架构
shaoming37765 小时前
检查系统硬件配置是否满足PyCharm最低要求
android·spring boot·mysql
空中海6 小时前
02 React Native状态、导航、数据流与设备能力
javascript·react native·react.js
一起搞IT吧6 小时前
高通Camx功能feature分析之十五:insensor zoom介绍及实现
android·智能手机·相机
空中海7 小时前
04 React Native工程化、质量、发布与生态选型
javascript·react native·react.js