【问题标题】:How to use 32-bit native libraries on 64-bit Android device如何在 64 位 Android 设备上使用 32 位本机库
【发布时间】:2022-01-21 23:58:03
【问题描述】:

我在我的应用程序中使用了一个仅针对 armeabi、armeabi-v7a 和 x86 编译的本地库。

在三星 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)

不幸的是,该库是封闭源代码。有没有办法在不使用 64 位目标重新编译库的情况下解决这个问题?

【问题讨论】:

  • 我做到了。一种适用于 AOSP,另一种适用于动态类加载。我的情况实际上要简单得多。但我刚刚发现我包含的另一个本机库确实提供了 64 位 .so 文件,因此在最终 apk 的 /lib 文件夹中有一个 arm64-86 文件夹。可能这就是系统假设我在所有情况下都提供 64 位 .so 文件的原因。我将尝试重新编译这个仅支持 32 位的库,看看它是否有效。
  • 好主意。让我们知道(如果需要,请回答您自己的问题)。

标签: android android-ndk ndk-build


【解决方案1】:

当您在 Android 上安装 APK 时,系统会在 APK 的 lib 文件夹中查找原生库目录(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"
        }
    }
}

【讨论】:

  • 看起来不错,64 位文件夹与这个 sn-p 一起消失了。一旦我能找到一个 64 位的手机来重现,我会将答案标记为已接受
  • 出现错误 NDK 集成在当前插件中已弃用。考虑尝试新的实验性插件。
  • android.useDeprecatedNdk=true 添加到项目根目录下名为 gradle.properties 的文件中。顺便说一句,使用已弃用的集成并不会感到难过,因为使用 abiFilters 仍然是 atm 从 APK 中过滤掉 64 位库的最干净的方式。
  • 从今天(2019 年 8 月 1 日)起,您无法将 APK 提交到没有 64 位架构的 Google Play 商店。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2014-04-27
    • 2011-08-08
    • 2015-02-27
    • 2012-12-14
    • 1970-01-01
    • 2016-02-28
    • 1970-01-01
    • 2012-11-18
    相关资源
    最近更新 更多