Android外部库访问问题:JNI方法stringFromJNI无法解析
解决Android中无法解析JNI方法
stringFromJNI的问题 嘿,我看你已经按教程搭好了jniLibs的文件夹结构,但JNI方法stringFromJNI找不到,大概率是这几个常见环节出了问题,我帮你一步步排查:
1. 先核对JNI方法的签名,必须丝毫不差
Java里声明的native方法,和C/C++代码里的方法签名得完全匹配——包名、类名、方法名,甚至参数和返回值类型都不能错。
举个例子,假设你的Java类是com.example.myapp.MainActivity,那代码里得这么声明:
public class MainActivity extends AppCompatActivity { static { System.loadLibrary("你的SO库名称"); // 划重点:别加.so后缀!比如libtest.so就写"test" } public native String stringFromJNI(); // 这个方法名必须和C/C++里的对应上 }
对应的C/C++代码里的方法得是这个格式:
#include <jni.h> #include <string> // C++代码必须加extern "C",不然会因为名字修饰找不到方法! extern "C" JNIEXPORT jstring JNICALL Java_com_example_myapp_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); }
注意:方法名必须是
Java_包名_类名_方法名的格式,包名里的.要换成_,C++代码一定要加extern "C",不然编译器会给方法名加奇怪的修饰,Java就找不到了。
2. 确认SO库加载是否正确
- 你在
static代码块里调用System.loadLibrary("xxx")时,xxx是SO文件的前缀名。比如你的SO文件叫libnative-lib.so,那就要写System.loadLibrary("native-lib"),不能带lib前缀和.so后缀。 - 可以检查下APK里有没有你的SO文件:把APK解压,看看
lib/armeabi/和lib/armeabi-v7a/目录下有没有对应的SO,如果没有,那就是Android Studio没把SO打包进去,得看配置。
3. 检查Gradle配置是否正确
默认情况下Android Studio会识别src/main/jniLibs,但有时候可能需要手动在Module级别的build.gradle里指定:
android { sourceSets { main { jniLibs.srcDirs = ['src/main/jniLibs'] } } }
如果你是用CMake或者ndk-build编译SO库的,还要确保Gradle关联了构建脚本:
android { externalNativeBuild { cmake { path "src/main/cpp/CMakeLists.txt" version "3.22.1" // 换成你用的CMake版本 } } }
4. 检查CPU架构兼容性
你只放了armeabi和armeabi-v7a的SO,那得确保测试设备的CPU是这俩架构之一,或者在build.gradle里指定支持的架构:
android { defaultConfig { ndk { abiFilters 'armeabi', 'armeabi-v7a' } } }
要是你的测试设备是x86架构,又没有对应的SO,也会加载失败,进而找不到JNI方法。
5. 清理缓存重建项目试试
有时候Android Studio的缓存会搞事情,试试:
- 点菜单栏的
Build->Clean Project - 然后
Build->Rebuild Project - 实在不行重启下Android Studio再运行
先从这几个方面排查,大部分JNI方法找不到的问题都是这些环节出了错。
内容的提问来源于stack exchange,提问作者Steve Malek
相关产品推荐
相关产品推荐

