我不是Android开发的新手,但在谈到NDK和.so库时,我是一个新手。
我正在构建的应用使用第三方SDK,它们提供了一些.so文件。他们为我提供了每个架构的.so文件(到目前为止:arm64-v8a,armeabi,armeabi-v7a,mips,mips64,x86,x86_64)。
我需要添加一个新的第三方SDK,但它们只为armeabi-v7a和x86提供.so文件。 当我尝试运行我的应用程序时,它崩溃了,我从SDK中得到一个错误(我在logcat上看到它)声明:
SDKNAME 目前仅为 armeabi-v7a 和 x86 架构提供预建库
这是一种常见情况吗?有没有办法解决这种情况?
提前多多感谢
答案 0 :(得分:4)
您需要为您的应用程序支持的所有体系结构提供所有库。
安装APK后,安装程序会扫描APK以了解它支持的体系结构。如果APK不包含本机代码,则它支持所有体系结构。但是,如果它确实包含本机代码,则它仅支持APK中包含的那些体系结构。大多数现代设备支持多种架构;例如,设备可能支持arm64-v8a
和armeabi-v7a
,或x86_64
和x86
,或x86
和armeabi-v7a
(通过仿真)。在安装时,它会查看包含哪些体系结构,选择最适合的体系结构,并安装该体系结构中的所有库,而忽略其余的。 (较旧的Android版本可能无意中在所描述的情况下显示略有不同,不一致的行为 - 请参阅https://stackoverflow.com/a/25648943/3115956。)
现在,如果您包含的某个库包含所有可用体系结构的构建,而另一个库仅支持少数几个,则安装程序可能会选择例如arm64-v8a
,因此无法获得所有必需的库。
因此,您只能支持所有库提供的架构交叉。
要实现此目的,您可以手动从提供更多体系结构的SDK中删除多余的目录,或者如果使用Gradle构建APK,则可以将其添加到NDK块:
abiFilters 'armeabi-v7a', 'x86'
答案 1 :(得分:1)
将已编译的库存储在app / src / main / jniLibs / {arch}中,例如:armeabi / armeabi-v7a,然后将帖子末尾的行添加到您的应用build.gradle。
productFlavours用于配置编译变体,这样就可以正确链接已编译的库。
android.ndk {
moduleName = "your_library_jni"
cppFlags.add("-fexceptions")
cppFlags.add("-std=c++11")
cppFlags.add("-I" + file("src/main/jni").absolutePath)
}
android.productFlavors {
create("x86") {
ndk.with{
abiFilters.add("armeabi")
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi/"
ldLibs.add(libsDir + "libyour_module.so")
}
}
create("arm-v7a") {
ndk.with {
abiFilters.add("armeabi-v7a")
File curDir = file('./')
curDir = file(curDir.absolutePath)
String libsDir = curDir.absolutePath + "/src/main/jniLibs/armeabi-v7a/"
ldLibs.add(libsDir + "libyour_module.so")
}
}
}