這章主要從4個方面對JNI進(jìn)行了闡述:
1.JNI的注冊,靜態(tài)注冊和動態(tài)注冊
2.Java和JNI層的類型轉(zhuǎn)換
3.JNIEnv和jstring的用法唐断,類型簽名
4.垃圾回收和異常處理
JNI的使用掂林,JNI是Java層調(diào)用Native層的接口傅物。

image.png
以MediaScanner為例:
Java層:
frameworks/base/media/java/android/media/MediaScanner.java
static {
System.loadLibrary("media_jni"); //加載so庫原叮,在java層,會接上lib,為libmedia_jni.so
native_init();k
}
//聲明native接口
private static native final void native_init();
Native層:
文件:
frameworks/base/media/jni/android_media_MediaScanner.cpp //這里的命名是packagename+classname
static void android_media_MediaScanner_native_init(JNIEnv *ent){
jclass clazz = env->FindClass(kClassMediaScanner); //這個就是得到MediaScanner.cpp類
}
MediaScanner.cpp文件即是最后執(zhí)行函數(shù)的地方:
frameworks/av/media/libmedia/MediaScanner.cpp
Java層和Native層函數(shù)的關(guān)聯(lián)即為注冊濒蒋,分為靜態(tài)注冊和動態(tài)注冊
靜態(tài)注冊則是通過javah,生成頭文件
javah -d /Users/longcheng/Documents/AndroidCode/DemoCode/JNIDemo/app/src/main/jni(jni的目錄)
動態(tài)注冊
a.添加到JNINativeMethod結(jié)構(gòu)體
static JNINativeMethod methods[] = {
{"stringFromJni", "()Ljava/lang/String;", (void*)getCLanguageString},
};
b.調(diào)用register
static int registerNativeMethods(JNIEnv* env , const char* className , JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
c.通過ONLoad加載
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
assert(env != NULL);
//動態(tài)注冊嗤练,自定義函數(shù)
if (!registerNatives(env)) {
return -1;
}
return JNI_VERSION_1_4;
}