Android JNI 开发
一、JNI 与 Android
JNI 是 Java 提供的用于在跨平台系统中,与系统本地代码进行交互的一层应用程序接口。在 Android 中,同样支持 JNI 开发,通过 Android 提供的 NDK 工具,可快速构建 JNI 开发环境,并且可以快速整合到 Android 项目中。
JNI 编译出的 .so 文件具有较高的安全性,反编译难度高,在一些涉及到安全层面的场合,可以考虑使用 JNI 编程。在 Android 平台,JNI 编程主要依赖于 C 或 C++ 编程环境。
二、JNI 开发流程
集成 NDK 工具
在 Android 平台进行 JNI 开发,需要集成 NDK 工具,该工具可直接通过 Android Studio 相关管理界面下载、配置,这里不再累述。

声明 native 方法
在项目中创建一个类,并声明相关 native 方法。
public class JNIs {
public static native String getString();
}
编译并生成 .h 头文件
在 Android Studio 中直接 build 或者通过 javac
命令生成该类的 class 文件。build 命令自动生成的 class 文件夹路径如下图所示:

也可以通过 javac
指定生成 class 文件的路径,定位到 java 类所在路径,通过如下命令将 class 文件生成到该目录下:
javac JNIs.java
若想指定 class 文件的输出目录,只需添加 -d 参数即可:
javac -d [目录] JNIs.java
生成 class 文件后,通过 java 将 .h 头文件输出,添加 -d 参数可将头文件输入至指定目录:
javah -d ../jni com.example.demo.mylibrary.JNIs
自动生成的 .h 头文件中的方法名称已严格按照指定规则命名,不能随意修改。
实现 native 方法
在相同的目录下新建 cpp 文件,文件名自定义,include 之前生成的 .h 文件,并实现相关方法:
//
// Created by me on 2019-08-18.
//
#include "com_example_demo_mylibrary_JNIs.h"
#include <stdio.h>
JNIEXPORT jstring JNICALL Java_com_example_demo_mylibrary_JNIs_getString
(JNIEnv * env, jclass clazz) {
return env -> NewStringUTF("hello, jni!");
}
在 build.gradle 文件中声明 JNI module 信息:
android {
// ...
defaultConfig {
// ...
ndk {
moduleName "jniTest"
abiFilters "armeabi","armeabi-v7a","x86"
}
}
}
执行 build,Android Studio 会在项目的 build 文件夹下自动生成对应的 Android.mk 文件,无需手动配置。同时,对应的 .so 文件也被自动生成了。

使用 so 库
生成 .so 之后,需要将该文件和对应声明 native 方法的类一起 copy 至调用方项目环境中。并在使用该库的地方做如下声明:
public class JNIs {
static {
System.loadLibrary("jniTest");
}
public static native String getString();
}
loadLibrary() 方法传入的 libName 参数严格按照在 build.gradle 文件中声明的 moduleName 为准。
更多 Android NDK 的相关内容请参见:
三、总结
JNI 的内容涉及众多,比如 Java 数据类型与 JNI 数据类型之间的对应关系、JNI 类型签名、JNI 与 Java 对象互操作等。
想了解更多关于 JNI 的知识,建议查阅官方文档:
JNI Specification >>
JNI Types and Data Structures >>
JNI Functions >>
本文由
Fynn_ 原创,未经许可,不得转载!