什么是JNI和NDK
- JNI是Java Native Interface的缩写,我大致把他理解成一种支持Java和c/c++交互的技术。对于Android来说,使用JNI开发项目,通常有以下优点。
- 提高程序运行速度
- 防止反编译
- 有些库只有c/c++版本,jni提供了Java与其交互的能力
- NDK是Native Development Kit的缩写,是用于支持在java中开发c/c++的组件。要实现JNI开发就必须用到NDK。AS中支持一键下载此开发包。
JNI从零开始开发流程
由于是浅谈,这里只做大概流程的梳理,不展开细讲。
- 编写接口:jni的Java类
该类实例化后是用于调用c/c++函数的Java对象,类似于Java的Interface或者c/c++的头文件,在这里定义需要用到的函数,并且加native关键词修饰。
因此通常情况下该类的函数不包含方法体,方法体在后面的步骤用c/c++来实现。例如:
public native String getName()
- 实现函数:编写c/c++代码
使用javah命令根据刚才的jni类来自动生成头文件,然后新建c/cpp导入头文件,编写方法体。
c/c++代码的编写需要参照jni标准,方法名按照“Java_包名_类名_函数名”的格式来对应jni类中的定义。使用jni的数据类型,且c/c++相关代码一般放在module/src/main/cpp路径下。 - 编写项目构建文件
有两种构建c/c++项目的方式:ndk-build和cmake。
ndk-build的配置文件为Android.mk和Application.mk,针对系统有所不同。
cmake的配置文件为CMakeLists.txt,支持跨平台。
以cmake为例, 配置文件需要配置c/c++文件路径,是否共享,编译后的库名。
配置文件编写完成后使用AS的Link C++ Project with Gradle功能把cmake和Gradle连接起来,以后编译Android项目时就会同时编译c/c++代码了。 - 加载so库,调用c/c++函数
在第一部新建的jni类中使用System.loadLibrary(String libname)来加载so库,加载成功后native函数便于c/c++连接成功,调用jni类中的函数即可。