如何在64位Android设备上使用32位本机库

Phi*_* E. 54 android android-ndk ndk-build

我在我的应用程序中使用本机库,该库仅为armeabi,armeabi-v7a和x86编译.

在像Samsung S6这样的64位设备上加载此库时,应用程序崩溃并出现UnsatisfiedLinkError

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.myapp-2/base.apk"],nativeLibraryDirectories=[/data/app/com.myapp-2/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "libfoo.so"
    at java.lang.Runtime.loadLibrary(Runtime.java:366)
    at java.lang.System.loadLibrary(System.java:989)
Run Code Online (Sandbox Code Playgroud)

不幸的是,图书馆是封闭的来源.有没有办法解决这个问题而无需使用64位目标重新编译库?

ph0*_*h0b 133

当您在Android上安装APK时,系统将lib按照确定的顺序在APK 的文件夹中查找本机库目录(armeabi,armeabi-v7a,arm64-v8a,x86,x86_64,mips64,mips)Build.SUPPORTED_ABIS.

如果您的应用程序碰巧有一个arm64-v8a缺少库的目录,则不会从另一个目录安装缺少的库,这些库不会混合.这意味着您必须为每个体系结构提供完整的库集.

因此,要解决您的问题,您可以从构建中删除64位库,或者将abiFilters设置为仅打包32位架构:

android {
    ....
    defaultConfig {
        ....
        ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 将`android.useDeprecatedNdk = true`添加到项目根目录下名为gradle.properties的文件中.顺便说一句,使用不推荐的集成感觉并不好,因为使用abiFilters仍然是从APK中过滤掉64位库的最简洁方式. (11认同)
  • 从今天(2019年8月1日)开始,您无法在没有64位体系结构的情况下将APK提交到Google Play商店。 (2认同)

小智 6

上述答案将有助于生成 32 位而非 64 位的构建。如果您使用 [ abiFilters "armeabi", "armeabi-v7a", "x86", "mips" ]。生成签名的 apk 意味着,这不适用于 64 位。当我们上传到 Google Play 商店时,它会引发错误。它不是 64 位版本。