上篇文章追踪runApplication函数到c++层,这篇文章分析一下c++与js的通信代码。
基础知识 Android系统加载JNI Lib的方法
Android系统加载JNI Lib的方法有如下两种:
1) 通过JNI_OnLoad
2) 如果JNI Lib没有定义JNI_OnLoad,则dvm调用dvmResolveNativeMethod进行动态解析
//我们知道,系统初始化JNI在加载时,会调用JNI_OnLoad(),而卸载时会调用JNI_UnLoad();所以,我们可以通过重写
JNI_OnLoad(),在JNI_OnLoad()中(JNIEnv->RegisterNatives函数)将函数注册到Android中,以便能通过Java访问。
入口是ReactBridge.java对应的c++实现文件。
Assertions.assertNotNull(mBridge).callFunction(moduleId, methodId, arguments);
其中mBridge在CatalystInstance中被初始化
mBridge
=
new
ReactBridge(
jsExecutor
,
new
NativeModulesReactCallback()
,
mCatalystQueueConfiguration
.getNativeModulesQueueThread())
;
moduleId是AppRegistry methodId是runApplication.
首先我们看看JNI_Onload都干了啥,在Onload.cpp
yin因此callFunction是由bridge::callFunction实现的。
这里与ReactBridge.java中的接口有明显的一一对应关系。
private native void initialize(
JavaScriptExecutor jsExecutor,
ReactCallback callback,
MessageQueueThread nativeModulesQueueThread);
public native void loadScriptFromAssets(AssetManager assetManager, String assetName);
public native void loadScriptFromNetworkCached(String sourceURL, @Nullable String tempFileName);
public native voidcallFunction(int moduleId, int methodId, NativeArray arguments);
public native void invokeCallback(int callbackID, NativeArray arguments);
public native void setGlobalVariable(String propertyName, String jsonEncodedArgument);
public native boolean supportsProfiling();
public native void startProfiler(String title);
public native void stopProfiler(String title, String filename);
下面是callFunction函数的实现 在同一文件。
static void callFunction(JNIEnv* env, jobject obj, jint moduleId, jint methodId,
NativeArray::jhybridobject args) {
auto bridge = extractRefPtr<Bridge>(env, obj);
auto arguments = cthis(wrap_alias(args));
std::vector<folly::dynamic> call{
(double) moduleId,
(double) methodId,
std::move(arguments->array),
};
try {