Android中JNI实现Java与C++交互,Java控制生命周期、C++处理计算密集任务;需声明native方法、加载so库,C++端显式注册函数映射并处理类型转换。

在 Android 开发中,C++ 通过 JNI(Java Native Interface)与 Java 交互,核心是让 Java 调用 C++ 函数,或 C++ 主动调用 Java 方法。这不是“C++ 主导”的开发模式,而是 Java 控制生命周期、C++ 承担计算密集型任务(如音视频处理、算法、游戏引擎等)。关键不在于“怎么写 C++”,而在于“怎么让两边正确握手”。
Java 层:声明 native 方法 + 加载 so 库
Java 类中用 native 关键字声明方法,不写实现;并在静态代码块中加载对应动态库(.so 文件):
public class NativeBridge {
// 声明一个 native 方法,签名需与 C++ 函数严格匹配
public static native String getStringFromCpp();
// 加载 libnative-lib.so(注意:前缀 "lib" 和后缀 ".so" 由系统自动处理)
static {
System.loadLibrary("native-lib");
}
}
调用时直接像普通方法一样用:String s = NativeBridge.getStringFromCpp();
C++ 层:实现 JNI 函数 + 注册映射
Android NDK 编译的 C++ 代码需导出符合 JNI 规范的函数名,或显式注册函数映射。推荐显式注册——更清晰、支持重命名、避免符号名过长。
立即学习“Java免费学习笔记(深入)”;
基本结构如下:
本文档主要讲述的是Android中JNI编程的那些事儿;JNI译为Java本地接口。它允许Java代码和其他语言编写的代码进行交互。在android中提供JNI的方式,让Java程序可以调用C语言程序。android中很多Java类都具有native接口,这些接口由本地实现,然后注册到系统中。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
- 包含头文件:
#include - 实现函数(参数固定为
JNIEnv*、jclass或jobject、后续为 Java 方法参数) - 定义
JNINativeMethod数组,声明 Java 方法名、签名、C++ 函数指针 - 在
JNI_OnLoad中调用RegisterNatives完成绑定
#include#include static jstring stringFromCpp(JNIEnv *env, jclass clazz) { return env->NewStringUTF("Hello from C++!"); } static const JNINativeMethod methods[] = { {"getStringFromCpp", "()Ljava/lang/String;", (void *)stringFromCpp}, }; JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env; if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) { return JNI_ERR; } jclass clazz = env->FindClass("com/example/NativeBridge"); env->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(methods[0])); return JNI_VERSION_1_6; }
类型转换:Java 与 C++ 的数据桥接
JNI 提供了一套标准类型映射,不能直接传对象,必须手动转换:
-
int↔jint,boolean↔jboolean,String↔jstring(用env->GetStringUTFChars()读,env->NewStringUTF()写) - 数组:如
int[]对应jintArray,用env->GetIntArrayElements()获取指针,操作完调env->ReleaseIntArrayElements() - 对象/类:用
env->FindClass()获取类,env->GetMethodID()获取方法,再用env->CallObjectMethod()等调用
⚠️ 注意:所有 NewXXX 创建的对象都可能触发 GC,返回前确保引用有效;字符串 UTF-8 和 UTF-16 需区分(GetStringUTFChars 返回修改版,慎用)。
构建与部署:CMake + Android Studio
现代 Android 项目用 CMake 构建 C++ 代码:
- 在
app/CMakeLists.txt中添加add_library(native-lib SHARED ...) - 用
find_library(log-lib log)引入系统库 - 在
app/build.gradle的android.defaultConfig下配置externalNativeBuild和 ABI(如armeabi-v7a,arm64-v8a) - 编译后生成的
.so会自动打包进 APK 的lib/目录/
运行时,System.loadLibrary("native-lib") 会按当前 CPU 架构自动加载对应 so。
基本上就这些。JNI 不复杂但容易忽略细节:签名写错、没释放数组、跨线程调 JNIEnv、混淆导致方法找不到……建议从一个 return "hello" 小例子开始跑通全流程,再逐步加逻辑。










