What
首先解释下JNI是什么,Java Native Interface,Java本地化接口。众所周知Java是跨平台的语言,依托于不同平台的JVM运行。当Java需要和原生平台进行沟通时,这个时候就需要用道JNI,通过C/C++代码来实现Java的代码,这样Java就可以和原生代码(C/C++)进行相互调用了。
NDK: Native Develop Kit,是Android提供原生开发工具包。是为了更加方便JNI的开发,同时NDK里面还包含和交叉编译等工具。
Why
- Java毕竟依托于JVM,本质上jdk的核心代码中的核心实现也都是去通过JNI去调用系统的库。
 - 原生代码相对于Java来说执行效率更高。同时核心实现Java完成不了的也是需要JNI。
 - 原生代码进行编译生成的库,相对于Java的jar来说反编译难度更大,安全性更高。
 - 便于移植
 
How
一个简单的JNI步骤
定义文件
1  | package com.test;  | 
javac编译
1  | javac com/test/JniTest.java  | 
javah生成头文件
1  | javah com.test.JniTest  | 
之后src下会生成com_test_JniTest.h文件,这里面就是我们即将写的C/C++代码的头文件了。
1  | /* DO NOT EDIT THIS FILE - it is machine generated */  | 
里面就是包含了引用jni库,方法声明
JNI结构
方法的命名形如:Java_com_test_JniTest_set以Java+包名+类名+方法名,中间使用下划线进行隔开。
数据类型
基础类型
基本上在Java的基础类型的基础上加上小写的j即可,比如:
1  | int -> jint  | 
tips:这里只是将Java的数据类型映射到C++中,不可以和C++的类型进行混淆。
引用类型
普通对象
1  | Object -> jobject  | 
数组
1  | Object[] -> jobjectArray  | 
基本上以此类推
签名
C++调用Java
之前第一个步骤是Java调用C++,当然反过来也是可以的。既然我们在native方法中是会传入关于JVM环境,以及对象等。我们可以通过反射进行类加载,来调用方法。
Java文件有个方法
1  | public static void test(String str) {  | 
C++中
这里我们调用静态方法
1  | void call_java_method(JNIEnv *env, jobject thiz)  | 
调用普通普通方法
1  |