《Android的设计与实现:卷I》——第2章 2.3 JNI总管:JNIEnv

简介: 本节书摘来自华章出版社《Android的设计与实现:卷I》——第2章,第2.3节。作者: 杨云君著.更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.3 JNI总管:JNIEnv

在Log系统的实例中,JNI层实现方法和注册方法中都使用了JNIEnv这个指针,通过它调用JNI函数,访问Java虚拟机,进而操作Java对象。JNIEnv是JNI编程中最重要的概念,本节将详细介绍它。首先看JNIEnv的体系结构,如图2-2所示。


image

在图2-2中可以看到,JNIEnv首先指向一个线程相关的结构,该结构又指向一个指针数组,在这个指针数组中的每个元素最终指向一个JNI函数。所以可以通过JNIEnv去调用JNI函数。

打开jni.h文件看看这部分内容是如何设计的。由于不同平台上有不同的jni.h文件,只需要取一个加以分析,这里打开libnativehelper/include/nativehelper/jni.h。

在jni.h中,为了兼容C和C++两种代码,使用宏__cplusplus加以区分。
首先看JNIEnv在文件中是如何定义的:


image

这里仅仅是用typedef关键字做了类型定义。那么_JNIEnv和JNINativeInterface又是什么类型呢?_JNIEnv结构体的源码如下:

以上是对 const struct JNINativeInterface类型的包装,并间接调用了const struct JNINativeInterface 上定义的方法。继续分析JNINativeInterface 的定义,代码如下:
struct JNINativeInterface {
……
jclass (FindClass)(JNIEnv, const char);
jint (ThrowNew)(JNIEnv , jclass, const char );
……

这里才真正涉及JNI函数的调用。当然,这里也只是个接口,具体的实现要参考虚拟机实现。

最终可以得到如下结论:

C++中:JNIEnv就是struct _JNIEnv。 JNIEnv env等价于struct _JNIEnvenv,在调用JNI函数的时候,只需要env-> FindClass(JNIEnv, const char),就会间接调用JNINativeInterface结构体里定义的函数指针,而无需首先对env解引用。

C中:JNIEnv就是const struct JNINativeInterface。JNIEnv env实际等价于const struct JNINativeInterface? env,因此要得到JNINativeInterface结构体内的函数指针就必须先对env解引用得到(env),即const struct JNINativeInterface,这个指针才是真正指向JNINativeInterface结构体的指针,然后再通过它调用具体的JNI函数。因此需要这样调用:(env)-> FindClass(JNIEnv, const char)。

注意 JNIEnv只在当前线程中有效。本地方法不能将JNIEnv从一个线程传递到另一个线程中。相同的 Java 线程中对本地方法多次调用时,传递给该本地方法的JNIEnv是相同的。但是,一个本地方法可被不同的 Java 线程所调用,因此可以接受不同的 JNIEnv。

相关文章
|
6月前
|
Android开发
Android JNI与CAN通信遇到的问题总结
Android JNI与CAN通信遇到的问题总结
219 1
|
6月前
|
Android开发
Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
877 1
|
3月前
|
Java Android开发 C++
Android Studio JNI 使用模板:c/cpp源文件的集成编译,快速上手
本文提供了一个Android Studio中JNI使用的模板,包括创建C/C++源文件、编辑CMakeLists.txt、编写JNI接口代码、配置build.gradle以及编译生成.so库的详细步骤,以帮助开发者快速上手Android平台的JNI开发和编译过程。
223 1
|
6月前
|
Java 开发工具 Android开发
OpenCV(一):Android studio jni配置OpenCV(亲测有效,保姆级)
OpenCV(一):Android studio jni配置OpenCV(亲测有效,保姆级)
637 0
|
6月前
|
Java Android开发
Android JNI 调用
Android JNI 调用
34 1
|
Java Android开发
Android JNI开发从0到1,java调C,C调Java,保姆级教程详解
Android JNI开发从0到1,java调C,C调Java,保姆级教程详解
87 1
|
6月前
|
传感器 Java 开发工具
[NDK/JNI系列03] Android Studio集成NDK开发环境
[NDK/JNI系列03] Android Studio集成NDK开发环境
64 0
|
Java Android开发 C++
Android中的JNI开发,你了解多少?
Android中的JNI开发,你了解多少?
97 0
|
6月前
|
Android开发
[Android jni] Bitmap与Mat对象的相互转换
[Android jni] Bitmap与Mat对象的相互转换
206 0
|
Java Android开发
[Android JNI] --- JNI基础(下)
[Android JNI] --- JNI基础(下)
82 0
下一篇
无影云桌面