ReactNative 源码分析7——Native Modules通信机制 之Js调用Java

2 阅读6分钟

NativeModules导入

import { NativeModules } from 'react-native';

//调用方式
NativeModules.MyButton.xxx()

我们看看NativeModules是什么

//NativeModules.js
let NativeModules: {[moduleName: string]: $FlowFixMe, ...} = {};
if (global.nativeModuleProxy) {
  NativeModules = global.nativeModuleProxy;
} else {
  ...
}

module.exports = NativeModules;

global.nativeModuleProxy是在JSIExecutor的initializeRuntime中初始化注入的

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

当调用NativeModules.NativeModuleDemo时触发C++的NativeModuleProxy.get方法

  • nativeModules_在前面分析过,它是JSINativeModules对象,里面包含ModuleRegistry对象
  • nativeModules = nativeModules_
class JSIExecutor::NativeModuleProxy : public jsi::HostObject {
 public:
  NativeModuleProxy(std::shared_ptr<JSINativeModules> nativeModules)
      : weakNativeModules_(nativeModules) {}

  Value get(Runtime& rt, const PropNameID& name) override {
    if (name.utf8(rt) == "name" ) {
      return jsi::String::createFromAscii(rt, "NativeModules" );
    }

    auto nativeModules = weakNativeModules_.lock();
    if (!nativeModules) {
      return nullptr;
    }

    return nativeModules->getModule(rt, name);
  }
  
  ...
};

所以这里调用的是JSINativeModules->getModule,核心作用:

  • 在m_objects缓存中查找模块,有则返回
  • createModule:创建模块
  • 将模块缓存到m_objects中
  • 返回Value(rt, result->second)
std::optional<Object> JSINativeModules::createModule(
    Runtime& rt,
    const std::string& name) {
  ...
  if (!m_genNativeModuleJS) {
    m_genNativeModuleJS =
        rt.global().getPropertyAsFunction(rt, "__fbGenNativeModule" );
  }

  auto result = m_moduleRegistry->getConfig(name);
  if (!result.has_value()) {
    return std::nullopt;
  }

  Value moduleInfo = m_genNativeModuleJS->call(
      rt,
      valueFromDynamic(rt, result->config),
      static_cast<double>(result->index));
  CHECK(!moduleInfo.isNull()) << "Module returned from genNativeModule is null" ;
  CHECK(moduleInfo.isObject())
      << "Module returned from genNativeModule isn't an Object" ;

  std::optional<Object> module(
      moduleInfo.asObject(rt).getPropertyAsObject(rt, "module" ));

  return module;
}

这里有个重要步骤

  • 查找JS中的__fbGenNativeModule全局方法,其实就是genModule
  • m_moduleRegistry->getConfig:获取模块
  • 调用__fbGenNativeModule全局方法
  • 返回module
//NativeModules.js
// export this method as a global so we can call it from native
global.__fbGenNativeModule = genModule;

生成模块

getConfig核心作用:使用一个JSON 数组描述一个NaitveModule的所有内容

std::optional<ModuleConfig> ModuleRegistry::getConfig(const std::string& name) {
  // Initialize modulesByName_
  if (modulesByName_.empty() && !modules_.empty()) {
    moduleNames();
  }

  auto it = modulesByName_.find(name);  
}
  • moduleNames:构建一个map对象modulesByName_,key=模块名、value=模块在modules_中的索引
  • modulesByName_.find返回模块索引
size_t index = it->second;

CHECK(index < modules_.size());
NativeModule* module = modules_[index].get();

// string name, object constants, array methodNames (methodId is index),
// [array promiseMethodIds], [array syncMethodIds]
folly::dynamic config = folly::dynamic::array(name);

std::vector<MethodDescriptor> methods = module->getMethods();

folly::dynamic methodNames = folly::dynamic::array;
folly::dynamic promiseMethodIds = folly::dynamic::array;
folly::dynamic syncMethodIds = folly::dynamic::array;

for (auto& descriptor : methods) {
  // TODO: # 10487027 compare tags instead of doing string comparison?
methodNames.push_back(std::move(descriptor.name));
  if (descriptor.type == "promise" ) {
    promiseMethodIds.push_back(methodNames.size() - 1);
  } else if (descriptor.type == "sync" ) {
    syncMethodIds.push_back(methodNames.size() - 1);
  }
}

if (!methodNames.empty()) {
  config.push_back(std::move(methodNames));
  if (!promiseMethodIds.empty() || !syncMethodIds.empty()) {
    config.push_back(std::move(promiseMethodIds));
    if (!syncMethodIds.empty()) {
      config.push_back(std::move(syncMethodIds));
    }
  }
}

然后获取到对应的NativeModule,并创建了一个JSON 数组,结构为:

[moduleName, constants, methodNames, promiseMethodIds?, syncMethodIds?]
//    [0]         [1]         [2]           [3]               [4]
  • constants:调用 module->getConstants() 获取导出常量(如 { "initialCount": 0 }
  • methodNames:调用 module->getMethods() 获取所有方法名
  • promiseMethodIds:记录哪些方法返回 Promise(索引列表)
  • syncMethodIds:记录哪些方法是同步的(索引列表)

这里不太好理解,我给大家举个例子就明白了,假设你有一个原生模块 MyButtonModule

@ReactModule(name = MyButtonModule.NAME)
class MyButtonModule(private val reactContext: ReactApplicationContext) :
    ReactContextBaseJavaModule(reactContext) {

    companion object {
        const val NAME = "MyButton"
    }

    override fun getName(): String = NAME

    // ── 常量导出 ──────────────────────────────────────
    // getConfig 返回的 config[1]
    override fun getConstants(): MutableMap<String, Any> {
        return mutableMapOf(
            "BUTTON_HEIGHT" to 44,
            "BUTTON_COLOR" to "#007AFF",
        )
    }

    // ── 异步方法(Async) ────────────────────────────────
    // getConfig 返回的 config[2] 中的普通方法
    @ReactMethod
    fun showAlert(message: String) {
        currentActivity?.runOnUiThread {
            Toast.makeText(it, message, Toast.LENGTH_SHORT).show()
        }
    }

    @ReactMethod
    fun getButtonState() {
        // 无返回值的异步调用,JS 侧无法获取结果
        // 如果需要返回值,应使用 Promise 或 Callback
    }
    
    // ── Callback 回调 ──────────────────────────────────
    // async 方法 + 最后参数为 Callback → genMethod 中走 nonPromiseMethodWrapper
    // JS 侧传入的 callback 会被识别为 onSuccess / onFail

    // 单个 callback
    @ReactMethod
    fun getButtonInfo(callback: Callback) {
        val map = Arguments.createMap().apply {
            putInt("height", 44)
            putString("color", "#007AFF")
            putBoolean("enabled", true)
        }
        callback.invoke(map)
    }

    // ── Promise 方法 ──────────────────────────────────
    // getConfig 返回的 config[3] 中的索引对应的方法
    @ReactMethod
    fun requestPermission(promise: Promise) {
        try {
            // 模拟权限请求
            val granted = true
            if (granted) {
                promise.resolve(true)
            } else {
                promise.reject("PERMISSION_DENIED", "User denied permission")
            }
        } catch (e: Exception) {
            promise.reject("ERROR", e)
        }
    }

    // ── 同步方法(Sync) ────────────────────────────────
    // getConfig 返回的 config[4] 中的索引对应的方法
    // 注意:同步方法不能返回 null
    @ReactMethod(isBlockingSynchronousMethod = true)
    fun isAvailable(): Boolean {
        return true
    }
}

那么 getConfig("MyButton") 返回的 config 数组是:

[
  "MyButton",                          // [0] 模块名
  {                                     // [1] 常量
    "BUTTON_HEIGHT": 44,
    "BUTTON_COLOR": "#007AFF"
  },
  [                                     // [2] 所有方法名(按声明顺序)
    "showAlert",
    "getButtonState",
    "requestPermission",
    "isAvailable"
  ],
  [2],                                  // [3] Promise 方法的索引 → requestPermission
  [3]                                   // [4] Sync 方法的索引 → isAvailable
]

最后返回值结构 ModuleConfig

struct ModuleConfig {
    size_t index;       // 模块在 modules_ 数组中的索引
    folly::dynamic config;  // JSON 配置数组
};

继续回到调用__fbGenNativeModule=genModule全局方法

function genModule(
  config: ?ModuleConfig,
  moduleID: number,
): ?{
  name: string,
  module?: {...},
  ...
} {
  if (!config) {
    return null;
  }

  //先从config中解析
  const [moduleName, constants, methods, promiseMethods, syncMethods] = config;
  invariant(
    !moduleName.startsWith( 'RCT' ) && !moduleName.startsWith( 'RK' ),
    "Module name prefixes should've been stripped by the native side " +
      "but wasn't for " +
      moduleName,
  );

  //模块中没有常量和方法
  if (!constants && !methods) {
    // Module contents will be filled in lazily later
    return {name: moduleName};
  }

  const module: {[string]: mixed} = {};
  methods &&
    methods.forEach((methodName, methodID) => {
      const isPromise =
        (promiseMethods && arrayContains(promiseMethods, methodID)) || false;
      const isSync =
        (syncMethods && arrayContains(syncMethods, methodID)) || false;
      invariant(
        !isPromise || !isSync,
        'Cannot have a method that is both async and a sync hook' ,
      );
      const methodType = isPromise ? 'promise' : isSync ? 'sync' : 'async' ;
      module[methodName] = genMethod(moduleID, methodID, methodType);
    });

  Object.assign(module, constants);

  if (module.getConstants == null) {
    module.getConstants = () => constants || Object.freeze({});
  } else {
    console.warn(
      `Unable to define method 'getConstants()' on NativeModule ' ${moduleName} ' . NativeModule ' ${moduleName} ' already has a constant or method called 'getConstants' . Please remove it.`,
    );
  }

  if (__DEV__) {
    BatchedBridge.createDebugLookup(moduleID, moduleName, methods);
  }

  return {name: moduleName, module};
}
  • 创建module对象
  • 这里遍历从config中解析的methods,获取方法类型:Promise方法、Sync方法
  const module: {[string]: mixed} = {};
  methods &&
    methods.forEach((methodName, methodID) => {
      const isPromise =
        (promiseMethods && arrayContains(promiseMethods, methodID)) || false;
      const isSync =
        (syncMethods && arrayContains(syncMethods, methodID)) || false;
      invariant(
        !isPromise || !isSync,
        'Cannot have a method that is both async and a sync hook' ,
      );
      const methodType = isPromise ? 'promise' : isSync ? 'sync' : 'async' ;
      module[methodName] = genMethod(moduleID, methodID, methodType);
    });

调用genMethod构造methodName对应的function,这个function在后面调用方法时会被触发

  • promise方法返回promiseMethodWrapper
  • 否则返回nonPromiseMethodWrapper
function genMethod(moduleID: number, methodID: number, type: MethodType) {
  let fn = null;
  if (type === 'promise' ) {
    fn = function promiseMethodWrapper(...args: Array<mixed>) {
      const enqueueingFrameError: ExtendedError = new Error();
      return new Promise((resolve, reject) => {
        BatchedBridge.enqueueNativeCall(
          moduleID,
          methodID,
          args,
          data => resolve(data),
          errorData =>
            reject(
              updateErrorWithErrorData(
                (errorData: $FlowFixMe),
                enqueueingFrameError,
              ),
            ),
        );
      });
    };
  } else {
    fn = function nonPromiseMethodWrapper(...args: Array<mixed>) {
      const lastArg = args.length > 0 ? args[args.length - 1] : null;
      const secondLastArg = args.length > 1 ? args[args.length - 2] : null;
      const hasSuccessCallback = typeof lastArg === 'function' ;
      const hasErrorCallback = typeof secondLastArg === 'function' ;
      hasErrorCallback &&
        invariant(
          hasSuccessCallback,
          'Cannot have a non-function arg after a function arg.' ,
        );
      // $FlowFixMe[incompatible-type]
      const onSuccess: ?(mixed) => void = hasSuccessCallback ? lastArg : null;
      // $FlowFixMe[incompatible-type]
      const onFail: ?(mixed) => void = hasErrorCallback ? secondLastArg : null;
      // $FlowFixMe[unsafe-addition]
      const callbackCount = hasSuccessCallback + hasErrorCallback;
      const newArgs = args.slice(0, args.length - callbackCount);
      if (type === 'sync' ) {
        return BatchedBridge.callNativeSyncHook(
          moduleID,
          methodID,
          newArgs,
          onFail,
          onSuccess,
        );
      } else {
        BatchedBridge.enqueueNativeCall(
          moduleID,
          methodID,
          newArgs,
          onFail,
          onSuccess,
        );
      }
    };
  }
  // $FlowFixMe[prop-missing]
  fn.type = type;
  return fn;
}

methods遍历完成后module对象内容如下

{
    showAlert(msg) { /* 通过 bridge 异步调用 index=0 */ },
    getButtonState() { /* 通过 bridge 异步调用 index=1 */ },
    getButtonInfo() {/* 返回 bridge, 调用 index=2 */}
    requestPermission() { /* 返回 Promise, 调用 index=3 */ },
    isAvailable() { /* 同步调用 index=4 */ },
}

接着构建constants

Object.assign(module, constants);

if (module.getConstants == null) {
  module.getConstants = () => constants || Object.freeze({});
}

constants完成后module对象内容如下

{
    BUTTON_HEIGHT: 44,
    BUTTON_COLOR: "#007AFF",
    showAlert(msg) { /* 通过 bridge 异步调用 index=0 */ },
    getButtonState() { /* 通过 bridge 异步调用 index=1 */ },
    getButtonInfo() {/* 返回 bridge, 调用 index=2 */}
    requestPermission() { /* 返回 Promise, 调用 index=3 */ },
    isAvailable() { /* 同步调用 index=4 */ },
}

最后整个genModule返回,也就是说JS 侧收到后Native返回的模块config后,会将其转化为可调用的JS对象:

{name: moduleName, module}

// JS 侧最终效果
{
    name: "MyButton",
    module: {
          BUTTON_HEIGHT: 44,
          BUTTON_COLOR: "#007AFF",
          showAlert(msg) { /* 通过 bridge 异步调用 index=0 */ },
          getButtonState() { /* 通过 bridge 异步调用 index=1 */ },
          getButtonInfo() {/* 返回 bridge, 调用 index=2 */}
          requestPermission() { /* 返回 Promise, 调用 index=3 */ },
          isAvailable() { /* 同步调用 index=4 */ },
    }
};

也就是说下面这个调用流程绕了一大圈干了 2 件核心事情

  • 从Native层获取module配置信息
  • 在JS构建一个对象,与Native层module配置信息一一对应
//JS层构建模块对象
NativeModules.MyButton --- JS层
    NativeModuleProxy.get --- C++层
        m_moduleRegistry->getConfig --- C++层获取模块信息
        genModule(config) --- JS层,将模块信息传入js
            genMethod --- JS层,将模块信息转化为可调用的JS对象
                |
返回JS对象<------|
//JS层调用模块方法(下面接着分析)

调用方法

接下来我们继续看方法调用

NativeModules.MyButton.xxx()

promise方法调用promiseMethodWrapper,它里面是调用

BatchedBridge.enqueueNativeCall

非promise方法调用nonPromiseMethodWrapper,里面分为同步和异步

//同步调用
BatchedBridge.callNativeSyncHook

//异步调用
BatchedBridge.enqueueNativeCall

异步调用

BatchedBridge是MessageQueue

enqueueNativeCall(
  moduleID: number,
  methodID: number,
  params: mixed[],
  onFail: ?(...mixed[]) => void,
  onSucc: ?(...mixed[]) => void,
): void {
  this.processCallbacks(moduleID, methodID, params, onFail, onSucc);

  this._queue[MODULE_IDS].push(moduleID);
  this._queue[METHOD_IDS].push(methodID);
  this._queue[PARAMS].push(params);

  const now = Date.now();
  if (
    global.nativeFlushQueueImmediate &&
    now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS
  ) {
    const queue = this._queue;
    this._queue = [[], [], [], this._callID];
    this._lastFlush = now;
    global.nativeFlushQueueImmediate(queue);
  }
  ...
}

它核心做了这几件事

  • 调用processCallbacks,保存onFail和onSucc回调,key是_callID,后续返回数据时会根据_callID找到对应的onFail和onSucc回调
processCallbacks(
  moduleID: number,
  methodID: number,
  params: mixed[],
  onFail: ?(...mixed[]) => void,
  onSucc: ?(...mixed[]) => void,
): void {
  if (onFail || onSucc) {
    onFail && params.push(this._callID << 1);
    // eslint-disable-next-line no-bitwise
    onSucc && params.push((this._callID << 1) | 1);
    this._successCallbacks.set(this._callID, onSucc);
    this._failureCallbacks.set(this._callID, onFail);
  }
  ...
  //_callID+1,下一次使用
  this._callID++;
}
  • 把调用信息保存到_queue数组中
//   [0]          [1]        [2]      [3]
[moduleID数组, methodID数组, params, _callID]
  • 调用nativeFlushQueueImmediate,并将_queue作为参数传递过去,它调用到C++层的HostFunction
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();
        }));

callNativeModules中调用delegate_->callNativeModules,delegate_是JsToNativeBridge

  • 将calls转换为vector,每个MethodCall包含:模块、方法、参数、回调id
struct MethodCall {
  int moduleId;
  int methodId;
  folly::dynamic arguments;
  int callId;
}
  • 循环遍历所有methodCalls,并调用m_registry->callNativeMethod,m_registry是ModuleRegistry
void callNativeModules(
    [[maybe_unused]] JSExecutor& executor,
    folly::dynamic&& calls,
    bool isEndOfBatch) override {
  ...
  std::vector<MethodCall> methodCalls = parseMethodCalls(std::move(calls));
  BridgeNativeModulePerfLogger::asyncMethodCallBatchPreprocessEnd(
      (int)methodCalls.size());

  // An exception anywhere in here stops processing of the batch.  This
  // was the behavior of the Android bridge, and since exception handling
  // terminates the whole bridge, there's not much point in continuing.
  for (auto& call : methodCalls) {
    m_registry->callNativeMethod(
        call.moduleId, call.methodId, std::move(call.arguments), call.callId);
  }
  ...
}

在ModuleRegistry.callNativeMethod中根据moduleId找到模块NativeModule,然后调用invoke方法

modules_[moduleId]->invoke(methodId, std::move(params), callId);

要知道NativeModule是什么,我们先看看ModuleRegistry是在哪里创建的

void CatalystInstanceImpl::initializeBridge(
    ...
    moduleRegistry_ = std::make_shared<ModuleRegistry>(buildNativeModuleList(
    std::weak_ptr<Instance>(instance_),
    javaModules,
    cxxModules,
    moduleMessageQueue_));
    ...
}

buildNativeModuleList中有代码如下,所以:

  • Java的NativeModule是JavaNativeModule(JavaModuleWrapper.cpp)
  • C++的NativeModule是CxxNativeModule(CxxNativeModule.cpp)
//ModuleRegistryBuilder.cpp
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;
}

回到JavaNativeModule::invoke

  • messageQueueThread_:NativeModules线程
  • wrapper_是对Java层中module的引用
  • getMethod:找到Java层中"invoke"方法
  • 然后调用该module的"invoke"方法
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());
      });
}

那么wrapper_是什么呢,我们还是要回到初始化,看看getJavaModules返回的什么

initializeBridge(
    new InstanceCallback(this),
    jsExecutor,
    mReactQueueConfiguration.getJSQueueThread(),
    mNativeModulesQueueThread,
    mNativeModuleRegistry.getJavaModules(this),
    mNativeModuleRegistry.getCxxModules(),
    mInspectorTarget);
    
/* package */ Collection<JavaModuleWrapper> getJavaModules(JSInstance jsInstance) {
  ArrayList<JavaModuleWrapper> javaModules = new ArrayList<>();
  for (Map.Entry<String, ModuleHolder> entry : mModules.entrySet()) {
    if (!entry.getValue().isCxxModule()) {
      javaModules.add(new JavaModuleWrapper(jsInstance, entry.getValue()));
    }
  }
  return javaModules;
}

很显然wrapper_就是JavaModuleWrapper的引用,我们继续看JavaModuleWrapper中的Invoke方法

@DoNotStrip
public void invoke(int methodId, ReadableNativeArray parameters) {
  if (methodId >= mMethods.size()) {
    return;
  }

  mMethods.get(methodId).invoke(mJSInstance, parameters);
}

通过方法id找到方法再进行调用,在JavaMethodWrapper.invoke中先构建参数,然后通过mMethod.invoke调用到指定的方法

//JavaMethodWrapper.java
@Override
public void invoke(JSInstance jsInstance, ReadableArray parameters) {
    ...
    int i = 0, jsArgumentsConsumed = 0;
    try {
      for (; i < mArgumentExtractors.length; i++) {
        mArguments[i] =
            mArgumentExtractors[i].extractArgument(jsInstance, parameters, jsArgumentsConsumed);
        jsArgumentsConsumed += mArgumentExtractors[i].getJSArgumentsNeeded();
      }
    } catch (UnexpectedNativeTypeException | NullPointerException e) {
        ...
    }

    mMethod.invoke(mModuleWrapper.getModule(), mArguments);
    ....
  } finally {
    SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush();
  }
}

到此JS->JAVA调用完整分析就完成了,异步调用不会直接返回数据,下一篇我们继续分析JAVA->JS返回数据

同步调用

同步调用的流程和前面分析的异步调用大体相似,所以同步调用我就说一下主要流程就可以了

BatchedBridge.callNativeSyncHook
    Value JSIExecutor::nativeCallSyncHook(const Value* args, size_t count)
        delegate_->callSerializableNativeHook
            m_registry->callSerializableNativeHook
                modules_[moduleId]->callSerializableNativeHook

调用到JavaNativeModule::callSerializableNativeHook后又调用method->invoke

MethodCallResult JavaNativeModule::callSerializableNativeHook(
    unsigned int reactMethodId,
    folly::dynamic&& params) {
  // TODO: evaluate whether calling through invoke is potentially faster
if (reactMethodId >= syncMethods_.size()) {
    throw std::invalid_argument(folly::to<std::string>(
        "methodId " ,
        reactMethodId,
        " out of range [0.." ,
        syncMethods_.size(),
        "]" ));
  }

  auto& method = syncMethods_[reactMethodId];
  CHECK(method.has_value() && method->isSyncHook())
      << "Trying to invoke a asynchronous method as synchronous hook" ;
  return method->invoke(instance_, wrapper_->getModule(), params);
}

这里的method是MethodInvoker

std::vector<std::optional<MethodInvoker>> syncMethods_;

MethodInvoker::invoke负责从 C++ 侧调用 Java 模块的方法,并将结果转回 folly::dynamic 供 JS 侧使用

这里会根据returnType类型调用不同代码片段,不同代码片段中根据参数类型调用不同方法

MethodCallResult MethodInvoker::invoke(
    std::weak_ptr<Instance>& instance,
    alias_ref<JBaseJavaModule::javaobject> module,
    const folly::dynamic& params) {
#ifdef WITH_FBSYSTRACE
  fbsystrace::FbSystraceSection s(
      TRACE_TAG_REACT_CXX_BRIDGE,
      isSync_ ? "callJavaSyncHook" : "callJavaModuleMethod" ,
      "method" ,
      traceName_);
#endif

  if (params.size() != jsArgCount_) {
    throw std::invalid_argument(folly::to<std::string>(
        "expected " , jsArgCount_, " arguments, got " , params.size()));
  }

  auto env = Environment::current();
  auto argCount = signature_.size() - 2;
  JniLocalScope scope(env, static_cast<int>(argCount));
  std::vector<jvalue> argsStorage(
      argCount + 1); // ensure we have at least 1 element
  jvalue* args = argsStorage.data();
  std::transform(
      signature_.begin() + 2,
      signature_.end(),
      args,
      [&instance, it = params.begin(), end = params.end()](char type) mutable {
        return extract(instance, type, it, end);
      });
//定义代码片段
#define PRIMITIVE_CASE(METHOD)                                             \
  {                                                                        \
    auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \
    throwPendingJniExceptionAsCppException();                              \
    return folly::dynamic(result);                                         \
  }

#define PRIMITIVE_CASE_CASTING(METHOD, RESULT_TYPE)                        \
  {                                                                        \
    auto result = env->Call##METHOD##MethodA(module.get(), method_, args); \
    throwPendingJniExceptionAsCppException();                              \
    return folly::dynamic(static_cast<RESULT_TYPE>(result));               \
  }

#define OBJECT_CASE(JNI_CLASS, ACTIONS)                                     \
  {                                                                         \
    auto jobject = env->CallObjectMethodA(module.get(), method_, args);     \
    throwPendingJniExceptionAsCppException();                               \
    if (!jobject) {                                                         \
      return folly::dynamic(nullptr);                                       \
    }                                                                       \
    auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \
    return folly::dynamic(result->ACTIONS());                               \
  }

#define OBJECT_CASE_CASTING(JNI_CLASS, ACTIONS, RESULT_TYPE)                \
  {                                                                         \
    auto jobject = env->CallObjectMethodA(module.get(), method_, args);     \
    throwPendingJniExceptionAsCppException();                               \
    if (!jobject) {                                                         \
      return folly::dynamic(nullptr);                                       \
    }                                                                       \
    auto result = adopt_local(static_cast<JNI_CLASS::javaobject>(jobject)); \
    return folly::dynamic(static_cast<RESULT_TYPE>(result->ACTIONS()));     \
  }

  //根据返回类型执行不同的代码片段
  char returnType = signature_.at(0);
  switch (returnType) {
    case 'v' :
      env->CallVoidMethodA(module.get(), method_, args);
      throwPendingJniExceptionAsCppException();
      return std::nullopt;

    case 'z' :
      PRIMITIVE_CASE_CASTING(Boolean, bool)
    case 'Z' :
      OBJECT_CASE_CASTING(JBoolean, value, bool)
    case 'i' :
      PRIMITIVE_CASE(Int)
    case 'I' :
      OBJECT_CASE(JInteger, value)
    case 'd' :
      PRIMITIVE_CASE(Double)
    case 'D' :
      OBJECT_CASE(JDouble, value)
    case 'f' :
      PRIMITIVE_CASE(Float)
    case 'F' :
      OBJECT_CASE(JFloat, value)

    case 'S' :
      OBJECT_CASE(JString, toStdString)
    case 'M' :
      OBJECT_CASE(WritableNativeMap, cthis()->consume)
    case 'A' :
      OBJECT_CASE(WritableNativeArray, cthis()->consume)

    default:
      LOG(FATAL) << "Unknown return type: " << returnType;
      return std::nullopt;
  }
}

最后数据通过folly::dynamic返回到JS 侧