JNI 基础知识

JNI 基础知识

什么是 JNI ?

JNI (Java Native Interface) 是 Java 沟通 Native 语言(主要是C、C++)的桥梁。
Native 语言有着更高的性能,更重要的是还有庞大的 Native 语言所编写的库。
这些给 Java 语言提供很多性能优秀的强大功能支持。
JNI 能够提供 Java 更快速的 Native 功能移植,也能利用 C++ 的反汇编能力加强代码安全性。

JNI 数据类型与 Java 、C++ 类型对比

Java 使用 JNI 最主要连接的 Native 语言是 C、C++(C++可以兼容C)。
因此这里介绍 Java 类型与 JNI 类型和 C++ 类型的对比关系。

Java 类型 JNI 类型 C++ 类型(包含封装的部分)
int jint / jsize long
long jlong __int64
byte jbyte signed char
boolean jboolean unsigned char
char jchar unsigned short
short jshort short
float jfloat float
double jdouble double
Object jobject _jobject*

Java 其它数据类型与 JNI 的关系

Java 还具有其它基础类型,为了方便调用也需要有 JNI 的类型进行对应。
基于常用的类型,有以下关系。
所有的 Class 都继承于 jobject,但是由于层次不一样。
不同的 jobject 的子类型有着不同的获取、调用和释放方式。

JNI 基础知识

JNI 各种对象的方法

方法 说明
FindClass 加载本地定义的类
GetObjectClass 通过对象获取这个类
NewObject 创建 jobject 类型的对象
NewString 创建 jstring 类型的对象
DeleteLocalRef 删除局部引用
DeleteGlobalRef 删除全局引用
New<Type>Array 创建类型为 Type 的数组对象
Get<Type>ArrayElements 从类型为 Type 的数组对象获取类型为 Type 的数组指针
Release<Type>ArrayElements 根据类型为 Type 的数组对象释放类型为 Type 的数组指针指向的资源
Get<Type>Field 获取类型为 Type 的字段
GetStatic<Type>Field 获取类型为 Type 的 static 字段
Set<Type>Field 设置类型为 Type 的字段
SetStatic<Type>Field 设置类型为 Type 的 static 字段
Call<Type>Method 调用类型为 Type 的方法
CallStatic<Type>Method 调用类型为 Type 的 static 方法

还有很多与类有关的方法,利用的频率不高就先不添加了。

JNI 域描述符

Java 类型 JNI 类型 域描述符 说明 示例
boolean jboolean Z
byte jbyte B
char jchar C
short jshort S
int jint I
long jlong J
float jfloat F
double jdouble D
int[] [I 一维数组形式,以一个 “[” 表示一维数组
byte[][] [[B N 维数组则以 N 个 “[” 表示 N 维
String jstring Ljava/lang/String; 类参数,则以 “Lxxx/yyy;” 的形式表示,注意 “L” 开头和 “;” 结尾。xxx/yyy 则是类的路径(都属于 jobject )
返回值 void V
函数形式 (xxx)yyy "()" 内为输入参数,右侧为输出参数

JNI 内存泄漏检查

由于 JNI 的机制,凡是创建 jobject 对象(包括其派生),都会在 Heap 申请资源。
及时不使用 jobject 对象,也会有资源占用。
导致退出时需要对 JNI 内的 jobject 对象资源释放。
(如果 jobject 返回到 Java 接口中,由 Java 进行回收)

对于新手的 JNI 开发来说,内存泄漏可能是必然存在的情况。
检查内存泄漏可以使用如下 adb 命令:


adb shell dumpsys meminfo packageName

检查 Native Heap 项,如下图。
JNI 基础知识