如何在Android应用中添加可作为Java方法调用的JNI C函数
在Android应用中添加可被Java调用的JNI C函数实现方案
方案1:通过Android Studio向导自动配置(适合首次接入JNI的项目)
- 打开目标Android项目,右键点击
app模块,选择New > Add C++ to Module - 弹出配置页后,C++ Standard可选择默认的
Toolchain Default,也可根据业务需求指定C++11/17等版本,点击Finish - 等待Gradle同步完成后,Android Studio会自动生成三类配置:
app/src/main/cpp/代码目录,默认包含native-lib.cpp示例文件app/CMakeLists.txtJNI构建脚本app/build.gradle中自动补全externalNativeBuild相关配置
- 在需要调用JNI的Java类中声明native方法,同时加载对应so库,示例:
public class MainActivity extends AppCompatActivity { // 声明native方法,具体实现由C层提供 public native String getStringFromJNI(); // 加载编译生成的so库,名称和CMakeLists.txt中配置的库名一致 static { System.loadLibrary("native-lib"); } }
- 打开
cpp目录下的C/C++文件,编写对应JNI实现,方法命名规则为Java_包名_类名_方法名,包名中的.需替换为_,示例:
#include <jni.h> #include <string> extern "C" JNIEXPORT jstring JNICALL Java_com_example_myapplication_MainActivity_getStringFromJNI(JNIEnv* env, jobject thiz) { std::string hello = "Hello from JNI C layer"; return env->NewStringUTF(hello.c_str()); }
注意:如果是纯C文件实现不需要加
extern "C",C文件必须添加该修饰,否则会因为C函数名粉碎机制导致Java层无法匹配到对应方法。
编译运行后即可直接在Java层调用声明的native方法。
方案2:手动修改构建文件配置(适合已有项目增量接入)
- 首先创建JNI代码目录:在
app/src/main/路径下新建cpp目录,在目录内新增你需要的C/C++文件,比如custom-jni.c,写入对应的JNI方法实现 - 在
app/模块根目录新建CMakeLists.txt文件,写入基础构建配置:
cmake_minimum_required(VERSION 3.22.1) project("myapplication") # 指定要编译的C/C++文件,生成名为custom-jni的so动态库 add_library( custom-jni SHARED custom-jni.c ) # 引入NDK自带的依赖库,此处示例引入log库用于JNI层打印日志 find_library( log-lib log ) # 把依赖库链接到自定义的so库中 target_link_libraries( custom-jni ${log-lib} )
- 修改
app/build.gradle文件,在android闭包下添加native构建配置:
android { // 原有配置保持不变 defaultConfig { // 原有配置保持不变 externalNativeBuild { cmake { cppFlags '' } } // 可选配置:指定需要编译的ABI架构,减小so包体积 ndk { abiFilters 'arm64-v8a', 'armeabi-v7a' } } externalNativeBuild { cmake { path file('CMakeLists.txt') version '3.22.1' } } }
- 同步Gradle后,在Java层声明对应native方法、加载
custom-jni库即可调用。
常见问题排查
- 调用JNI方法时抛出
UnsatisfiedLinkError:优先检查JNI方法命名是否符合规则、C++实现是否加了extern "C"、System.loadLibrary传入的库名是否和CMakeLists中配置的一致 - 构建时提示头文件找不到:检查CMakeLists.txt中是否通过
include_directories配置了头文件所在目录 - 运行时提示so库找不到:检查
ndk.abiFilters配置是否覆盖了当前运行设备的架构
内容的提问来源于stack exchange,提问作者user15052203
相关产品推荐
相关产品推荐

