导入Eclipse ADT项目至Android Studio后JNI函数无法解析求助
我之前迁移带JNI的Android项目时也踩过几乎一模一样的坑,给你几个针对性的排查和解决步骤,应该能搞定:
严格核对JNI函数签名
Android Studio对JNI签名的校验比Eclipse严格得多,哪怕是大小写、参数类型(比如int和long混淆,或者对象类型的L路径写错)都会导致运行时找不到函数。你可以用javah工具生成标准签名来对比:
在项目根目录执行命令:javah -d jni -classpath app/build/intermediates/javac/debug/classes 你的完整类名(比如com.example.MyJniClass)生成的头文件里的函数签名,和你.so文件里实际导出的函数名对比(可以用
nm -D libxxx.so查看.so的导出函数),看看有没有差异。确认jnilibs的目录结构
Android Studio要求.so文件必须放在对应CPU架构的子文件夹下,正确的结构应该是:src/main/jnilibs/ armeabi-v7a/ libxxx.so arm64-v8a/ libxxx.so x86/ libxxx.so如果你的
.so直接放在jnilibs根目录,AS大概率识别不到,自然找不到对应的JNI函数。检查app模块的build.gradle配置
确保gradle正确识别jnilibs路径,并且指定了匹配的ABI:android { sourceSets { main { // 明确指定jniLibs的路径,默认就是这个,但有时候迁移后会出问题 jniLibs.srcDirs = ['src/main/jnilibs'] } } defaultConfig { ndk { // 只保留你有对应.so的架构,避免打包多余架构导致的问题 abiFilters 'armeabi-v7a', 'arm64-v8a' } } }注意:如果用的是AGP 7.0+,ndk配置方式不变,但要确保你的SDK里安装了对应版本的NDK。
验证.so是否被打包进APK
把编译生成的APK解压,查看lib/目录下是否有对应架构的.so文件。如果没有,说明gradle没把.so打包进去,那运行时肯定找不到函数。这时候要检查gradle里有没有误加了排除jniLibs的配置,或者路径写错了。处理AS的静态检查提示
有时候Cannot resolve corresponding JNI function只是AS的静态检查误报,但如果你的功能确实无法运行,那肯定是实际存在问题。如果确认签名和路径都对,可以给对应的类或方法加@SuppressWarnings("JniMissingFunction")来消除提示,但这只是治标,核心还是要解决运行时的问题。核对.so加载代码
确保你的JNI类里加载库的代码正确:比如你的.so文件是libtest.so,那加载代码应该是System.loadLibrary("test")(不带lib前缀和.so后缀)。另外,加载操作最好放在静态代码块里,保证在调用本地方法前已经完成加载:static { System.loadLibrary("test"); }
内容的提问来源于stack exchange,提问作者Halil RAŞO

