美文网首页Android JNIAndroid开发Android技术知识
《深入理解Android:卷1》- JNI层(二)

《深入理解Android:卷1》- JNI层(二)

作者: Dufre | 来源:发表于2018-03-26 20:17 被阅读186次

    JNIEnv是什么?

    《深入理解Android:卷1》- JNI层(一)中,在JNI函数的注册方法中,不管是静态方法还是动态方法,其函数参数中第一个参数是一个接口指针,类型为JNIEnv。

    JNIEnv类型实际上代表了Java在本线程的运行环境,通过这个JNIEnv* 指针,就可以对Java端的代码进行操作。JNIEnv的指针会被JNI传入到本地方法的实现函数中来对Java端的代码进行操作。

    JNIEnv内部结构和作用

    JNIEnv是一个指向指针的指针,这个指针指向一个指针数组,指针数组中的每个指针指向接口函数。

    Description of Figure Interface Pointer.png

    这些接口函数的作用有两个:

    • 调用Java的函数(JNIEnv 代表 Java 运行环境,可以使用 JNIEnv 调用 Java 中的代码)
    • 操作jobject对象(Java层的对象到JNI层就是jobject对象,需要用JNIEnv来操作这个对象)

    一个Java对象包括:

    • 成员变量
    • 成员函数

    操作Java对象的本质就是操作这些对象的成员变量和成员函数,Java对象除了少数几个外,在JNI层都会用object来表示对象的数据类型。

    在JNI规则中,用 jfieldID和jmethodID来表示Java类的成员变量和成员函数:

    • jfieldID表示Java类的成员变量
    • jmethodID表示Java类的成员函数

    jfieldID和jmethodID可以通过两个函数得到:

    //jclass代表Java类,name表示成员函数或成员变量名,sig为这个函数的签名信息
    jfieldID GetFieldID(jclass clazz, const char *name, const char *sig)
    jmethodID GetMethodID(jclass clazz, const char *name, const char *sig)
    

    得到这两个参数后,JNI层调用Java对象的成员变量和成员函数时,传入jfieldID 或jmethodID;jobject和其他参数就可以实现调用了。

    JNIEnv与线程有关

    JNIEnv是一个与线程相关的变量。

    • 在JNI接口指针只在当前线程有效,一个本地方法不允许接口指针从一个线程到另
      一个线程。实现JNI的虚拟机可以通过JNI接口指针向指针指向的区域分配和存储线程本地数据。
    • 本地方法接收JNI接口指针作为实参。当它在同一个Java线程中对本机方法进行多次调用时,它保证会将相同的接口指针传递给本地方法。但是,可以从不同的Java线程调用本机方法,因此可以接收不同的JNI接口指针。

    JNIEnv与JavaVM的区别

    • JavaVM: JavaVM 是 Java虚拟机在 JNI 层的代表,JNI 全局只有一个
    • JNIEnv: JNIEnv是JavaVM 在线程中的代表, 每个线程都有一个,JNI 中可能有很多个 JNIEnv

    今日单词

    • Class methods: 类的成员方法
    • Class Fields: 类的成员变量

    参考文章

    相关文章

      网友评论

        本文标题:《深入理解Android:卷1》- JNI层(二)

        本文链接:https://www.haomeiwen.com/subject/pqcdcftx.html