chromium 中是如何使用C++和Java之间的相互调用的
chromium为方便JNI的开发, 写了一个关键脚本: jni_generator.py,
在编译前扫描所有的java文件, 对java文件中有@CalledByNative注解的方法和native关键字修饰的方法,
在out/release/gen/目录下生成和java文件对应的.h文件,
命名规则是: 类名_jni.h, 例如: Tab.java对应Tab_jni.h, TraceEvent.java对应TraceEvent_jni.h
以Tab.java为例:
public class Tab {
//内核获得用户输入的url
@CalledByNative
public String getUrl() {
String url = getWebContents() != null && !getWebContents().isDestroyed() ? getWebContents().getUrl() : "";
if (getContentViewCore() != null || getNativePage() != null || !TextUtils.isEmpty(url)) {
mUrl = url;
}
return mUrl != null ? mUrl : "";
}
//保存网页的API
private native void nativeSaveWebArchieve(long nativeTabAndroid, String filename, ValueCallback<String> callback);
}
对应着Tab_jni.h中的内容:
//生成一个方法对调用Java中的方法进行封装
//本质还是: 通过JNIEnv找到method id, 然后通过CallObjectMethod() 进行调用.
static base::android::ScopedJavaLocalRef<jstring> Java_Tab_getUrl(JNIEnv* env,
jobject obj) {
/* Must call RegisterNativesImpl() */
CHECK_CLAZZ(env, obj,
Tab_clazz(env), NULL);
jmethodID method_id =
base::android::MethodID::LazyGet<
base::android::MethodID::TYPE_INSTANCE>(
env, Tab_clazz(env),
"getUrl",
"("
")"
"Ljava/lang/String;",
&g_Tab_getUrl);
jstring ret =
static_cast<jstring>(env->CallObjectMethod(obj, //***这里实现的真正调用java中的方法***
method_id));
jni_generator::CheckException(env);
return base::android::ScopedJavaLocalRef<jstring>(env, ret);
}
总结:为了方便jni_generator.py脚本根据该注解识别java中需要在C中实现调用该java方法。