Java JNI 的本意是 Java Native Interface(Java 本地接口),他是为了方便 Java 调用 C、C++ 等本地代码所封装的一层接口。
NDK 是 Android 所提供的一个工具集合,通过 NDK 可以在 Android 中更加方便的通过 JNI 来访问本地代码。NDK 还提供了交叉编译器,开发人员只需要简单的修改 mk 文件就可以生成特定 CPU 平台的动态库。
JNI 的开发流程
- 在 Java 中声明 native 方法
- 编译 Java 源文件得到 class 文件,然后通过 javah 命令导出 JNI 的头文件
- 实现 JNI 方法
- 编译 so 库并在 Java 中调用
NDK 的开发流程
- 配置好 NDK
- 创建或导入一个 Android 项目,并声明所需要的 native 方法
- 实现 Android 项目中所声明的 native 方法
- 通过 ndk-build 命令编译产生 so 库
JNI 的数据类型
JNI 的数据类型包含两种:基本类型和引用类型
JNI 基本类型的对应关系
| JNI类型 | Java类型 | 描述 |
|---|---|---|
| jboolean | boolean | 无符号8位整型 |
| jbyte | byte | 有符号8位整型 |
| jchar | char | 无符号16位整型 |
| jshort | short | 有符号16位整型 |
| jint | int | 32位整型 |
| jlong | long | 64位整型 |
| jfloat | float | 32位浮点型 |
| jdouble | double | 64位浮点型 |
| void | void | 无类型 |
JNI 引用类型的对应关系
| JNI类型 | Java类型 | 描述 |
|---|---|---|
| jobject | Object | Object类型 |
| jclass | Class | Class类型 |
| jstring | String | 字符串 |
| jobjectArray | Object[] | 对象数组 |
| jbooleanArray | boolean[] | boolean数组 |
| jbyteArray | byte[] | byte数组 |
| jchartArray | chart[] | chart数组 |
| jshortArray | short[] | short数组 |
| jintArray | int[] | int数组 |
| jlongArray | long[] | long数组 |
| jfloartArray | floart[] | floart数组 |
| jdoubleArray | double[] | double数组 |
| jthrowable | Throwable | Throwable |
类型签名
JNI 的类型签名标识了一个特定的 Java 类型,这个类型既可以是类和方法,也可以是数据类型。
类的签名
类的签名采用"L+包名+类名+;"的形式,只需要将其中的.替换位/即可
java.lang.String ---> Ljava/lang/String;
注意末尾的;也是签名的一部分
基本数据类型的签名
基本数据类型的签名采用一系列大写字母来表示
| Java类型 | 签名 |
|---|---|
| boolean | Z |
| byte | B |
| char | C |
| short | S |
| int | I |
| long | J |
| float | F |
| double | D |
| void | V |
对象和数组的签名
对象的签名就是对象所属的类的签名
String ---> Ljava/lang/String;
数组的签名为 [+类型签名
int[] ----> [I
String[] -----> [Ljava/lang/String;
多维数据的签名为 n个[ + 类型签名,n表示数组的维度
int[][] ----> [[I
方法的签名
方法的签名为 (参数类型签名)+返回值类型签名
boolean fun(int a, String b, int[] c)
(ILjava/lang/String;[I)Z