深入理解JNI

这章主要从4个方面对JNI进行了阐述:
1.JNI的注册,静态注册和动态注册
2.Java和JNI层的类型转换
3.JNIEnv和jstring的用法,类型签名
4.垃圾回收和异常处理

JNI的使用,JNI是Java层调用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文件即是最后执行函数的地方:
frameworks/av/media/libmedia/MediaScanner.cpp

Java层和Native层函数的关联即为注册,分为静态注册和动态注册
静态注册则是通过javah,生成头文件

javah -d /Users/longcheng/Documents/AndroidCode/DemoCode/JNIDemo/app/src/main/jni(jni的目录) 

动态注册
a.添加到JNINativeMethod结构体

static JNINativeMethod methods[] = {
        {"stringFromJni", "()Ljava/lang/String;", (void*)getCLanguageString},
};

b.调用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);

    //动态注册,自定义函数
    if (!registerNatives(env)) {
        return -1;
    }

    return JNI_VERSION_1_4;
}

你可能感兴趣的:(深入理解JNI)