Android-ReactNative通信流程

JNI注册

Android中注册JNI方法有两种方式,一种是静态注册,一种是动态注册。

动态注册

因为JNI允许我们提供一个函数映射表(native函数和jni函数对应表)。而在执行System.loadLibrary加载so库时,会执行该so的JNI_OnLoad函数,利用这个时机可以动态注册JIN方法。具体实现的话是通过JNINativeMethod结构保存映射关系,然后通过RegisterNatives函数来将该映射关系注册。

静态注册

如果没有在JNI_OnLoad中将JNI方法注册(将方法在进程中的地址增加到ClassObject->directMethods中),则在调用的时候解析javah风格的函数(比如Java_com_example_hellojni_HelloJni_stringFromJNI),进行静态注册。静态注册根据函数名来建立java方法和jni函数的对应关系。静态注册需要根据方法名本地搜索,比较耗时。

RN中的JNI注册
JNI_OnLoad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# src/main/jni/react/jni/OnLoad.cpp
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
// 调用各个类的注册方法
return initialize(vm, [] {
gloginit::initialize();
JSCJavaScriptExecutorHolder::registerNatives();
ProxyJavaScriptExecutorHolder::registerNatives();
CatalystInstanceImpl::registerNatives();
CxxModuleWrapperBase::registerNatives();
CxxModuleWrapper::registerNatives();
JCxxCallbackImpl::registerNatives();
NativeArray::registerNatives();
NativeDeltaClient::registerNatives();
ReadableNativeArray::registerNatives();
WritableNativeArray::registerNatives();
NativeMap::registerNatives();
ReadableNativeMap::registerNatives();
WritableNativeMap::registerNatives();
ReadableNativeMapKeySetIterator::registerNatives();

#ifdef WITH_INSPECTOR
JInspector::registerNatives();
#endif
});
}
CatalystInstanceImpl.registerNatives

先拿CatalystInstanceImpl来举例子,先准备好映射数据,然后构建映射表,再通过FindClass获取对应java类的引用,通过这些参数使用RegisterNatives函数来注册。

1
2
3
4
5
6
7
8
9
10
11
# src/main/jni/react/jni/CatalystInstanceImpl.h 
class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
// 该类对应的Java类,通过该路径来加载java类的class引用
public:
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/CatalystInstanceImpl;";

static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
~CatalystInstanceImpl() override;

static void registerNatives();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# src/main/jni/react/jni/CatalysInstanceImpl.cpp 
void CatalystInstanceImpl::registerNatives() {
registerHybrid({
// 返回{java方法名,java类命名空间(CatalysInstanceImpl.kJavaDescriptor),JNIMethod指针}
makeNativeMethod("initHybrid", CatalystInstanceImpl::initHybrid),
makeNativeMethod("initializeBridge", CatalystInstanceImpl::initializeBridge),
makeNativeMethod("jniExtendNativeModules", CatalystInstanceImpl::extendNativeModules),
makeNativeMethod("jniSetSourceURL", CatalystInstanceImpl::jniSetSourceURL),
makeNativeMethod("jniRegisterSegment", CatalystInstanceImpl::jniRegisterSegment),
makeNativeMethod("jniLoadScriptFromAssets", CatalystInstanceImpl::jniLoadScriptFromAssets),
makeNativeMethod("jniLoadScriptFromFile", CatalystInstanceImpl::jniLoadScriptFromFile),
makeNativeMethod("jniLoadScriptFromDeltaBundle", CatalystInstanceImpl::jniLoadScriptFromDeltaBundle),
makeNativeMethod("jniCallJSFunction", CatalystInstanceImpl::jniCallJSFunction),
makeNativeMethod("jniCallJSCallback", CatalystInstanceImpl::jniCallJSCallback),
makeNativeMethod("setGlobalVariable", CatalystInstanceImpl::setGlobalVariable),
makeNativeMethod("getJavaScriptContext", CatalystInstanceImpl::getJavaScriptContext),
makeNativeMethod("jniHandleMemoryPressure", CatalystInstanceImpl::handleMemoryPressure),
});

JNativeRunnable::registerNatives();
}
registerHybrid

javaClassStatic函数是通过FindClass(name)来加载对应java类的class引用(加载的类名就是上面定义的kJavaDescriptor),得到jclass对象,而JClass是对它的包装。

1
2
3
static void registerHybrid(std::initializer_list<NativeMethod> methods) {
javaClassStatic()->registerNatives(methods);
}
JClass.registerNatives

将JNI函数映射表与该jclass对象绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# src/main/jni/first-party/fb/include/fb/fbjni/CoreClases-inl.h
inline void JClass::registerNatives(std::initializer_list<NativeMethod> methods) {
const auto env = internal::getEnv();
// 构建native和jni方法的映射关系表
JNINativeMethod jnimethods[methods.size()];
size_t i = 0;
for (auto it = methods.begin(); it < methods.end(); ++it, ++i) {
// JNINativeMethod结构包含方法名、方法签名、jni函数指针
jnimethods[i].name = it->name;
jnimethods[i].signature = it->descriptor.c_str();
jnimethods[i].fnPtr = reinterpret_cast<void*>(it->wrapper);
}
// 通过RegisterNatives函数来注册,参数为(java class引用,映射表,方法数)
// 所以这里的self()就是jclass
auto result = env->RegisterNatives(self(), jnimethods, methods.size());
FACEBOOK_JNI_THROW_EXCEPTION_IF(result != JNI_OK);
}

Java调用Js

JavaToJs流程

在Java层注册Js层module

在Java层提供了一系列的Js层module的接口类,里面定义了可以调用Js层module的方法。在Java层中通过代理创建这些接口的实例,让外层直接调用这些接口的方法。而方法的真正实现都会通过jni转向c++层,而后转向js层。

1
2
3
4
5
6
// 这就是AppRegistry.js的接口类,里面定义了Java层可以调用的三个方法
public interface AppRegistry extends JavaScriptModule {
void runApplication(String appKey, WritableMap appParameters);
void unmountApplicationComponentAtRootTag(int rootNodeTag);
void startHeadlessTask(int taskId, String taskKey, WritableMap data);
}
Java层
CatalystInstanceImpl.getJSModule

getJSModule方法是通过动态代理生成指定接口实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public synchronized <T extends JavaScriptModule> T getJavaScriptModule(
CatalystInstance instance,
Class<T> moduleInterface) {
// moduleInterface 就是对应JSModule的Java接口
// 取缓存
JavaScriptModule module = mModuleInstances.get(moduleInterface);
if (module != null) {
return (T) module;
}
// 通过Proxy创建动态代理对象
JavaScriptModule interfaceProxy = (JavaScriptModule) Proxy.newProxyInstance(
moduleInterface.getClassLoader(),
new Class[]{moduleInterface},
// 代理对象的具体实现是在InvocationHandler中
new JavaScriptModuleInvocationHandler(instance, moduleInterface));
// 缓存
mModuleInstances.put(moduleInterface, interfaceProxy);
return (T) interfaceProxy;
}

代理对象的真正实现是在InvocationHandler的invoke方法中。

1
2
3
4
5
6
7
8
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
NativeArray jsArgs = args != null
? Arguments.fromJavaArgs(args)
: new WritableNativeArray();
mCatalystInstance.callFunction(getJSModuleName(), method.getName(), jsArgs);
return null;
}
CatalystInstanceImpl.callFunction

将JSModuleName、MethodName、Args这三个参数传给C++层,通过C++层来传递给JS层。

1
2
3
4
5
6
7
8
9
10
11
12
public void callFunction(PendingJSCall function) {
if (!mAcceptCalls) {
synchronized (mJSCallsPendingInitLock) {
if (!mAcceptCalls) {
mJSCallsPendingInit.add(function);
return;
}
}
}
// 调用了JNI方法
function.call(this);
}
CatalystInstanceImpl.jniCallJSFunction
1
private native void jniCallJSFunction(String module,String method,NativeArray arguments);
C++层
CatalystInstanceImpl.jniCallJSFunction

最终会调用到NativeToJsBridge,它专门负责Native对Js的调用。

1
2
3
4
5
void CatalystInstanceImpl::jniCallJSFunction(std::string module, std::string method, NativeArray* arguments) {
instance_->callJSFunction(std::move(module),
std::move(method),
arguments->consume());
}
NativeToJsBridge.callFunction

所有的Native对Js的调用都由NativeToJsBridge来负责调度,所有Native对Js的调用都会发到JS消息线程中处理。

1
2
3
4
5
6
7
8
9
10
11
12
void NativeToJsBridge::callFunction(
std::string&& module,
std::string&& method,
folly::dynamic&& arguments) {
...
// 将消息发送到JS消息线程中处理
runOnExecutorQueue([module = std::move(module), method = std::move(method), arguments = std::move(arguments), systraceCookie]
(JSExecutor* executor) {
...
executor->callFunction(module, method, arguments);
});
}
JSCExecutor.callFunction

JSCExecutor负责与Js进行真正的接触,在JSCExecutor中保存了JS运行环境的全局变量MessageQueue对象的引用,以及其相关方法的引用。通过该对象的引用和方法引用,可以调用该对象的方法。这就是c++调用js方法的真相。

而m_callFunctionReturnFlushedQueueJS就是获取的MessageQueue.callFunctionReturenFlushedQueue函数引用。这些对象引用都是在bindBridge中进行的。

在callAsFunction中会通过JSC引擎来调用m_callFunctionReturnFlushedQueueJS这个函数。此时代码就进入了JS层。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void JSCExecutor::callFunction(
const std::string& moduleId,
const std::string& methodId,
const folly::dynamic& arguments) {

auto result = [&] {
JSContextLock lock(m_context);
try {
if (!m_callFunctionReturnResultAndFlushedQueueJS) {
// 绑定JS运行环境中的MessageQueue对象引用
bindBridge();
}
// 调用MessageQueue.callFunctionReturenFlushedQueue函数
return m_callFunctionReturnFlushedQueueJS->callAsFunction(
{Value(m_context, String::createExpectingAscii(m_context, moduleId)),
Value(m_context, String::createExpectingAscii(m_context, methodId)),
Value::fromDynamic(m_context, std::move(arguments))});
} catch (...) {
std::throw_with_nested(
std::runtime_error("Error calling " + moduleId + "." + methodId));
}
}();
// 返回的结果是js调用native方法的请求队列,处理这些请求
callNativeModules(std::move(result));
}
JSCExecutor.bindBridge

获取js环境中的全局属性 MessageQueue,以及MessageQueue中一些函数引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void JSCExecutor::bindBridge() throw(JSException) {
SystraceSection s("JSCExecutor::bindBridge");
std::call_once(m_bindFlag, [this] {
auto global = Object::getGlobalObject(m_context);
// 获取js运行环境的全局变量__fbBatchedBridge的引用
// __fbBatchedBridge就是MessageQueue对象实例
auto batchedBridgeValue = global.getProperty("__fbBatchedBridge");
if (batchedBridgeValue.isUndefined()) {
auto requireBatchedBridge =
global.getProperty("__fbRequireBatchedBridge");
if (!requireBatchedBridge.isUndefined()) {
batchedBridgeValue = requireBatchedBridge.asObject().callAsFunction({});
}
if (batchedBridgeValue.isUndefined()) {
throw JSException(
"Could not get BatchedBridge, make sure your bundle is packaged correctly");
}
}

auto batchedBridge = batchedBridgeValue.asObject();
// 获取MessageQueue的各个方法引用
// 获取MessageQueue.callFunctionReturnFlushedQueue函数引用
m_callFunctionReturnFlushedQueueJS =
batchedBridge.getProperty("callFunctionReturnFlushedQueue").asObject();
// 获取MessageQueue.invokeCallbackAndReturnFlushedQueue函数引用
m_invokeCallbackAndReturnFlushedQueueJS =
batchedBridge.getProperty("invokeCallbackAndReturnFlushedQueue")
.asObject();
// 获取MessageQueue.flushedQueue函数引用
m_flushedQueueJS = batchedBridge.getProperty("flushedQueue").asObject();
// 获取MessageQueue.callFunctionReturnResultAndFlushedQueue函数引用
m_callFunctionReturnResultAndFlushedQueueJS =
batchedBridge.getProperty("callFunctionReturnResultAndFlushedQueue")
.asObject();
});
}
Js层
MessageQueue.callFunctionReturnResultAndFlushedQueue
1
2
3
4
5
6
7
8
9
10
11
12
13
callFunctionReturnResultAndFlushedQueue(
module: string,
method: string,
args: any[],
) {
let result;
this.__guard(() => {
// 执行JS方法
result = this.__callFunction(module, method, args);
});
// 返回JS对Native方法调用请求的请求队列
return [result, this.flushedQueue()];
}
MessageQueue.__callFunction

getCallableModule会从所有注册的module列表中找到指定name的module。注册是通过MessageQueue.registerCallableModule来注册的。

1
2
3
4
5
6
7
8
9
__callFunction(module: string, method: string, args: any[]): any {
...
// 获取到指定Module对象
const moduleMethods = this.getCallableModule(module);
// 执行该对象的指定方法,这样就完成了Java层对JS方法的调用
const result = moduleMethods[method].apply(moduleMethods, args);
Systrace.endEvent();
return result;
}
1
2
// 比如这就是AppRegistry Module的注册
BatchedBridge.registerCallableModule('AppRegistry', AppRegistry);
MessageQueue全局属性

在c++层获取的全局属性__fbBatchedBridge,就是在这里注册的,其值就是MessageQueue对象实例。

1
2
3
4
5
6
const BatchedBridge = new MessageQueue();

Object.defineProperty(global, '__fbBatchedBridge', {
configurable: true,
value: BatchedBridge,
});

Js调用Java

JsToJava流程

在Js层注册Java层module
NativeModules (JS层)

global.nativeModuleProxy是在c++层的JSCExecutor创建的时候设置的,值是所有Java层module列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 将genModule设置成全局属性,方便c++层调用该方法创建js层的java module对象。
global.__fbGenNativeModule = genModule;

let NativeModules: {[moduleName: string]: Object} = {};
if (global.nativeModuleProxy) {
// 获取全局变量nativeModuleProxy,将其导出
NativeModules = global.nativeModuleProxy;
} else if (!global.nativeExtensions) {
// 如果c++层并没有设置该值,则自己手动创建
// __fbBatchedBridgeConfig是在c++层设置的Java层module的配置列表
const bridgeConfig = global.__fbBatchedBridgeConfig;
const defineLazyObjectProperty = require('defineLazyObjectProperty');
(bridgeConfig.remoteModuleConfig || []).forEach(
(config: ModuleConfig, moduleID: number) => {
// 创建js层java module对象
const info = genModule(config, moduleID);
if (!info) {
return;
}
if (info.module) {
NativeModules[info.name] = info.module;
}
else {
defineLazyObjectProperty(NativeModules, info.name, {
get: () => loadModule(info.name, moduleID),
});
}
},
);
}
module.exports = NativeModules;
设置nativeModuleProxy (C++层)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
JSCExecutor::JSCExecutor(
std::shared_ptr<ExecutorDelegate> delegate,
std::shared_ptr<MessageQueueThread> messageQueueThread,
const folly::dynamic& jscConfig) throw(JSException)
: m_delegate(delegate),
m_messageQueueThread(messageQueueThread),
m_nativeModules(delegate ? delegate->getModuleRegistry() : nullptr),
m_jscConfig(jscConfig) {
initOnJSVMThread();

{
// 设置js运行环境全局属性nativeModuleProxy
installGlobalProxy(
m_context,
"nativeModuleProxy",
exceptionWrapMethod<&JSCExecutor::getNativeModule>());
}
}
JSCNativeModules.getModule (C++层)
1
2
3
4
5
6
7
8
JSValueRef JSCNativeModules::getModule(JSContextRef context, JSStringRef jsName) {
...
// 创建module
auto module = createModule(moduleName, context);
...
auto result = m_objects.emplace(std::move(moduleName), std::move(*module)).first;
return static_cast<JSObjectRef>(result->second);
}
JSCNativeModules.createModule (C++层)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
folly::Optional<Object> JSCNativeModules::createModule(const std::string& name, JSContextRef context) {
if (!m_genNativeModuleJS) {
// 获取NativeModules.genModule函数
auto global = Object::getGlobalObject(context);
m_genNativeModuleJS = global.getProperty("__fbGenNativeModule").asObject();
m_genNativeModuleJS->makeProtected();
}
// 获取该module的配置信息,方法描述签名集合等
auto result = m_moduleRegistry->getConfig(name);
if (!result.hasValue()) {
return nullptr;
}
// 根据module的配置信息,调用genModule函数创建js层的java module对象
Value moduleInfo = m_genNativeModuleJS->callAsFunction({
Value::fromDynamic(context, result->config),
Value::makeNumber(context, result->index)
});

folly::Optional<Object> module(moduleInfo.asObject().getProperty("module").asObject());

ReactMarker::logTaggedMarker(ReactMarker::NATIVE_MODULE_SETUP_STOP, name.c_str());
return module;
}
ModuleRegistry.getConfig (C++层)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
folly::Optional<ModuleConfig> ModuleRegistry::getConfig(const std::string& name) {
auto it = modulesByName_.find(name);
size_t index = it->second;
NativeModule *module = modules_[index].get();

folly::dynamic config = folly::dynamic::array(name);
{
// 获取module中定义的常亮
config.push_back(module->getConstants());
}
{
// 获取module中定义的方法
std::vector<MethodDescriptor> methods = module->getMethods();

folly::dynamic methodNames = folly::dynamic::array;
folly::dynamic promiseMethodIds = folly::dynamic::array;
folly::dynamic syncMethodIds = folly::dynamic::array;
...
if (config.size() == 2 && config[1].empty()) {
return nullptr;
} else {
return ModuleConfig{index, config};
}
}
JavaNativeModule.getConstants (C++层)
1
2
3
4
5
6
7
8
9
10
11
folly::dynamic JavaNativeModule::getConstants() {
// 调用Java层的JavaModuleWrapper的getConstants方法
static auto constantsMethod =
wrapper_->getClass()->getMethod<NativeMap::javaobject()>("getConstants");
auto constants = constantsMethod(wrapper_);
if (!constants) {
return nullptr;
} else {
return cthis(constants)->consume();
}
}
JavaNativeModule.getMethods (C++层)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::vector<MethodDescriptor> JavaNativeModule::getMethods() {
std::vector<MethodDescriptor> ret;
syncMethods_.clear();
// 调用Java层的JavaModuleWrapper获取所有由ReactMethod注解标记的方法
auto descs = wrapper_->getMethodDescriptors();
for (const auto& desc : *descs) {
auto methodName = desc->getName();
auto methodType = desc->getType();
...
ret.emplace_back(
std::move(methodName),
std::move(methodType)
);
}
return ret;
}
JavaModuleWrapper.getMethodDescriptors (Java层)

获取该module中所有拥有ReactMethod注解标记的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
private void findMethods() {
Set<String> methodNames = new HashSet<>();

Class<? extends NativeModule> classForMethods = mModuleClass;
Class<? extends NativeModule> superClass =
(Class<? extends NativeModule>) mModuleClass.getSuperclass();
if (ReactModuleWithSpec.class.isAssignableFrom(superClass)) {
classForMethods = superClass;
}
Method[] targetMethods = classForMethods.getDeclaredMethods();

for (Method targetMethod : targetMethods) {
// 该方法是否拥有ReactMethod注解
ReactMethod annotation = targetMethod.getAnnotation(ReactMethod.class);
if (annotation != null) {
String methodName = targetMethod.getName();
MethodDescriptor md = new MethodDescriptor();
JavaMethodWrapper method = new JavaMethodWrapper(this, targetMethod, annotation.isBlockingSynchronousMethod());
md.name = methodName;
md.type = method.getType();
if (md.type == BaseJavaModule.METHOD_TYPE_SYNC) {
md.signature = method.getSignature();
md.method = targetMethod;
}
// 加入方法列表
mMethods.add(method);
mDescs.add(md);
}
}
}
NativeModules.genModule (JS层)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function genModule(
config: ?ModuleConfig,
moduleID: number,
): ?{name: string, module?: Object} {

// 提取出Java module 配置信息中的属性
const [moduleName, constants, methods, promiseMethods, syncMethods] = config;
// 创建Moduel对象
const module = {};
methods && // 为module创建所有的方法
methods.forEach((methodName, methodID) => {
const methodType = isPromise ? 'promise' : isSync ? 'sync' : 'async';
// 创建方法
module[methodName] = genMethod(moduleID, methodID, methodType);
});
Object.assign(module, constants);
return {name: moduleName, module};
}
NativeModules.genMethod (JS层)

为所有的Java module对象创建需要的方法,并提供实现(此处类似于Java层创建接口和代理对象一样)。在JS层创建Java module在JS层中虚假对象和方法,便于外部直接调用Java module的方法,该对象的方法实现和代理对象一样,都会传递到C++层中,然后通过C++层传递到Java层。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function genMethod(moduleID: number, methodID: number, type: MethodType) {
let fn = null;
if (type === 'promise') {
...
} else if (type === 'sync') {
...
} else {
// 所有Java module方法的真实实现
fn = function(...args: Array<any>) {
// 通过MessageQueue调用c++层,然后c++层调用Java层对象,执行Java module的方法
BatchedBridge.enqueueNativeCall(
moduleID,
methodID,
args,
onFail,
onSuccess,
);
};
}
fn.type = type;
return fn;
}

至此,所有的Java module都在JS层创建了一个虚假对象,该对象持有module中注册的方法,在JS中可以直接通过普通对象的方式来调用,而module方法的真正实现就是上面的 fn ,会调向c++层。

Js层
NativeModules.xxxNativeModule.xxxMethod

由于上面讲过,在JS层为每个Java module 都创建了一个虚拟对象和方法实现,所以可以通过普通对象一样调用Java module。而这些许虚拟对象的方法实现都是上面的 fn 函数。所以会调用BatchedBridge.enqueueNativeCall方法。

1
2
3
4
5
6
7
8
const NativeModules = require('NativeModules');
// 想要调用UIManagerModule.createView方法
UIManager.createView(
tag, // reactTag
viewConfig.uiViewClassName, // viewName
rootContainerInstance, // rootTag
updatePayload // props
);
MessageQueue.enqueueNativeCall

在MessageQueue中维护了一个队列_queue,这个队列中保存了每次JS层对Java module的调用请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
enqueueNativeCall(
moduleID: number,
methodID: number,
params: any[],
onFail: ?Function,
onSucc: ?Function,
) {

this._callID++;
// 将本次Java module方法调用请求加入队列中
this._queue[MODULE_IDS].push(moduleID);
this._queue[METHOD_IDS].push(methodID);
this._queue[PARAMS].push(params);

const now = new Date().getTime();
if (
global.nativeFlushQueueImmediate &&
now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS
) {
// 如果上一次刷新_queue队列距离现在已经过去5秒,则立刻刷新
const queue = this._queue;
this._queue = [[], [], [], this._callID];
this._lastFlush = now;
// nativeFlushQueueImmediate是在c++层添加的c++方法引用
global.nativeFlushQueueImmediate(queue);
}
// 否则,等待c++层主动来获取队列
}
C++层
JSCExecutor.nativeFlushQueueImmediate
1
2
3
4
5
6
7
8
9
10
JSValueRef JSCExecutor::nativeFlushQueueImmediate(
size_t argumentCount,
const JSValueRef arguments[]) {
if (argumentCount != 1) {
throw std::invalid_argument("Got wrong number of args");
}

flushQueueImmediate(Value(m_context, arguments[0]));
return Value::makeUndefined(m_context);
}
JsToNativeBridge.callNativeModules

JsToNativeBridge专门处理所有的Js层对Java层的调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void callNativeModules(
JSExecutor& executor, folly::dynamic&& calls, bool isEndOfBatch) override {

for (auto& call : parseMethodCalls(std::move(calls))) {
// 以此执行每次调用请求
m_registry->callNativeMethod(call.moduleId, call.methodId, std::move(call.arguments), call.callId);
}
if (isEndOfBatch) {
if (m_batchHadNativeModuleCalls) {
// 如果请求队列不为空,则执行完毕后通知Java层,JS层对Java层module调用处理完毕
m_callback->onBatchComplete();
m_batchHadNativeModuleCalls = false;
}
m_callback->decrementPendingJSCalls();
}
}
ModuleRegistry.callNativeMethod

该modules_列表是在CatalystInstanceImpl.initializeBridge时,创建ModuleRegistry对象时赋值的。

1
2
3
4
5
6
7
void ModuleRegistry::callNativeMethod(unsigned int moduleId, unsigned int methodId, folly::dynamic&& params, int callId) {
if (moduleId >= modules_.size()) {
throw std::runtime_error(
folly::to<std::string>("moduleId ", moduleId, " out of range [0..", modules_.size(), ")"));
}
modules_[moduleId]->invoke(methodId, std::move(params), callId);
}
JavaNativeModule.invoke
1
2
3
4
5
6
7
8
9
10
11
void JavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
// 在native消息线程中执行
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] {
static auto invokeMethod = wrapper_->getClass()->getMethod<void(jint, ReadableNativeArray::javaobject)>("invoke");
// 执行Java层JavaModuleWrapper.invoke方法
invokeMethod(
wrapper_,
static_cast<jint>(reactMethodId),
ReadableNativeArray::newObjectCxxArgs(std::move(params)).get());
});
}
JInstanceCallback.onBatchComplete

该ReactCallback对象是在CatalystInstanceImpl.initializeBridge注册的时候创建的一个BridgeCallback对象。

1
2
3
4
5
6
7
8
9
void onBatchComplete() override {
// 在native消息线程中
messageQueueThread_->runOnQueue([this] {
// 执行ReactCallback.onBatchComplete方法
static auto method =
ReactCallback::javaClassStatic()->getMethod<void()>("onBatchComplete");
method(jobj_);
});
}
Java层
JavaModuleWrapper.invoke
1
2
3
4
5
6
7
public void invoke(int methodId, ReadableNativeArray parameters) {
if (mMethods == null || methodId >= mMethods.size()) {
return;
}

mMethods.get(methodId).invoke(mJSInstance, parameters);
}
JavaMethodWrapper.invoke
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void invoke(JSInstance jsInstance, ReadableNativeArray parameters) {
String traceName = mModuleWrapper.getName() + "." + mMethod.getName();

try {
if (!mArgumentsProcessed) {
processArguments();
}

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 e) {
}

try {
// 反射执行真正的Java module的方法
mMethod.invoke(mModuleWrapper.getModule(), mArguments);
}
} finally {
}
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×