在进行 Android 开发中,使用 JNI 调用 C/C++ 代码是常见的需求。然而,在使用 JNI 调用时,有时会遇到找不到 so 库的问题。这篇博客将讨论在 Android 项目中出现这种问题时可能的原因,并提供解决方案。
问题描述
当你尝试在 Android 项目中加载 so 库时,可能会遇到以下错误:
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.test-1/base.apk", ....]]] couldn't find "libnative-lib.so"
这个错误通常发生在使用 JNI 进行本地方法调用时,它表示无法找到匹配的 so 库。在 Android 项目中,有两个常见的目录用于存放 so 库,即 jniLibs 和 libs。
解决方案
检查文件路径
首先,确保你的 so 库位于正确的位置。根据 Android Gradle 构建系统的不同版本,so 库需要放置在不同的目录下。
在 Android Gradle Plugin 3.0.0 及以上版本中,so 库应该放在 src/main/jniLibs
目录下。如果你将 so 库放在 src/main/libs
目录下,系统将无法找到它们。
然而,在 Android Gradle Plugin 2.3.0 及更早版本中,so 库应该放在 src/main/libs
目录下。
因此,检查你的项目配置和 Gradle 版本,并将 so 库放置在正确的目录下。
检查 ABI
Android 设备有不同的 CPU 架构(如 arm64-v8a,armeabi-v7a,x86 等),每种架构对应的 so 库应该放在正确的子目录下。
在 jniLibs 或 libs 目录下,你可以为每个架构创建一个子目录,并将相应架构的 so 库放在其中。例如,jniLibs/armeabi-v7a
目录用于存放 armeabi-v7a 架构的 so 库。
确保你的项目中包含了所有使用到的架构的 so 库,并将它们放置在正确的子目录下。
检查 Gradle 配置
在你的项目的 build.gradle 文件中,查找 ndk
和 jniLibs
或 abiFilters
相关的配置项。
确保 ndk 配置项指定了正确的 NDK 路径。例如:
android {
...
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
...
}
同时,如果你的项目使用了 abiFilters,确保它包含了你使用到的所有架构。
检查依赖库
如果你的项目依赖了其他库,并且那些库也包含了 JNI 调用和自己的 so 库,则需要注意处理它们的冲突。
确保依赖库的 so 库与你的项目中的 so 库不冲突并且正确加载。
清理和重新编译
如果你尝试了以上的解决方案仍然无效,可以尝试进行清理和重新编译。
运行以下命令清理项目:
./gradlew clean
然后重新编译项目:
./gradlew assembleDebug
其他注意事项
- 检查编译时产生的 build 文件夹,确保生成的 APK 包含了正确的 so 库。
- 确保 Android 设备支持你的应用所需的相应 CPU 架构。
结论
当 Android 项目无法找到 so 库时,可以通过检查文件路径、ABI、Gradle 配置、依赖库以及进行清理和重新编译来解决问题。希望这篇博客对于解决 Android 找不到 so 库的问题有所帮助。
参考资料:
本文来自极简博客,作者:柔情似水,转载请注明原文链接:Android 找不到so库 jniLibs和libs的问题