JNI 是什么?
JNI 是 Java Native Interface的缩写,意思是 Java本地接口,JNI 是一种技术,通过JNI我们可以实现:
1、Java 程序中可以调用 C/C++ 语言编写的Native函数。
2、C/C++ 程序中可以调用 Java 的方法。
为什么使用 JNI ?
1、使用现有的开源库,现在很多优秀的开源库都是用 C/C++ 编写的。
2、代码的保护,Android apk 的 java 代码容易被反编译,而 C/C++ 更难反编译。
3、便于移植,用 C/C++ 写的库可以方便在其他嵌入式平台使用。
AndroidStudio 如何开发 JNI ?
答案是NDK。
NDK 全称是 Native Development Kit,NDK 提供了一系列的工具,帮助开发者快速开发 C/C++ 的动态库,并能自动将 so 和 java 应用一起打包成 apk。这些工具对开发者的帮助是巨大的。
NDK 集成了交叉编译器,并提供了相应的 mk 文件隔离 CPU、平台、ABI 等差异,开发人员只需要修改 mk 文件,就可以创建出 so。
NDK 可以自动地将 so 和 Java 应用一起打包,极大地方便了打包工作。
AndroidStudio 如何配置 NDK ?
本文使用mac 上 AndroidStudio2.3.2 展示配置步骤
1、打开AndroidStudio,顶部找到Tools ,选择 Tools -> Android -> SDK Manager

2、在弹出的对话框选择 SDK Tools,下图中标1的部分

3、找到上图中的NDK,勾选,如上图中标2的部分
4、点击上图右下角 Apply 安装,等待安装完成
5、重启AndroidStudio,打开项目 Project 视图下 local.properties 文件,发现多了 ndk.dir 路径,表示安装完成

到这一步表示我们已经可以使用 AndroidStudio 方便的进行 JNI 开发了,下面我们进行 JNI 开发的详细步骤
JNI 开发详细步骤
1、新建一个Android工程

2、在MainActivity里增加本地方法

3、生成native方法对应的 .h 头文件
a)点击Android Studio 底部的Terminal,图标1
b)可以看到默认路径在当前工程下,图标2
c)执行 cd app/src/main/java 到java路径,也就是包名开始的路径,图标3
d)执行 javah -jni 包名+类名 ,图标4

执行完上面命令后,会看到在 java 路径下生成了.h文件

生成 .h 文件的内容如下:

可以看到我们的 getStringFromJni() 方法被转换成了 C/C++方法 JNIEXPORT jstring JNICALL Java_cn_le_ndk_MainActivity_getStringFromJni (JNIEnv *,jobject);
4、新建 .c 文件,实现上述方法
为了目录清晰,我们首先新建 jni 文件夹
在 src/main 目录点击右键 new -> Folder -> JNI Folder

新建JNI Folder 之后的目录如下,把上一步生成的 .h 文件移动到此目录

5、在 jni 文件夹下,右键新建 C 文件,文件名可以任意,实现 .h 里的函数

此文件里只实现了 cn_le_ndk_MainActivity.h 生成的一个函数。
到这时候,我们的 java 中 Native 方法声明,.h 文件生成, .c 文件实现,都已经完成了。
下面就是如何把 .c 文件编译成 so ,并自动打包的 apk 里。
6、配置 NDK 编译环境
.c 文件生成后,直接运行项目,发现报错

查看红框中的提示,项目中包含 c++ 文件,但是没有配置编译系统,接下来就用到我们在文章开头安装好的 ndk 插件了
切换项目为Project视图,
找到gradle.properties文件,增加以下android.useDeprecatedNdk=true,如下图所示:

7、配置 so 名字 和 输出 so 对应的平台
在 app 文件夹下的 build.gradle 中的 defaultConfig 里加入如下代码

8、运行项目,
发现在 app/build/intermediates/ndk/debug/lib 里多了我们编译的 so 文件,编译成功

9、查看运行结果,看到从 libhello_ndk.so 文件中读取的字符串,显示在了TextView中

总结:
至此,我们已经完成了 Android Studio 的 JNI 开发。我们看到可以分为3个部分:
1、配置 AndroidStudio NDK 环境,只需一次,以后所有的项目都可以用了。
2、建项目,编写 Native 方法,也是我们的主要实现。
3、配置项目的 NDK 编译,so 输出。
网友评论