在64位Android上使用32位JNI库

31

我尝试在Nexus 9上使用本地库运行应用程序。

该应用程序以错误消息退出:

java.lang.UnsatisfiedLinkError: dlopen failed: "lib_xyz.so" is 32-bit instead of 64-bit

除了重新编译库并使apk变大,是否有已知的解决此问题的方法?

7个回答

34
发现一个解释:64位的安卓系统可以将32位本地库作为备选项,只有在System.loadLibrary()在默认搜索路径找不到更好的选项时才会使用。 如果你强制使用完整库路径去加载32位库,会得到UnsatisfiedLinkError报错。 因此,第一个解决方法是使用System.loadLibrary()而不是System.load()。
还需要注意的是库不能混用:备选行为仅适用于应用程序加载的第一个库。如果第一个是64位的,则相同的应用程序无法加载32位库,反之亦然。

是的。我通过浏览Android源代码(实现库加载的方式)发现了它。 - G B
1
@gb 我知道这可能是老问题,但我们发现在Galaxy S6 Edge升级到Android 5.1.1后,这个功能不再起作用了。在此之前它是可以正常工作的。你知道是否有所改变吗?你能指出你找到这个信息的地方吗?谢谢! - Xavier Rubio Jansana
2
没事了,原因是其他的(值得记住在这种情况下要检查):我们为项目添加了一个依赖于JNI库的模块。这个库支持64位,在这种情况下兼容性回退被禁用了。 - Xavier Rubio Jansana
@GB 感谢分享这个见解!您介意告诉我在AOSP源代码中找到库加载实现的确切位置吗(最好是在Lollipop或更高版本上)?谢谢 :) - Roi Tal
1
如何解决这个崩溃?有没有针对这个问题的代码解决方案? - Anand Savjani
显示剩余3条评论

19

重点是将运行环境转换为32位

  1. build.gradle 中添加以下内容:

    defaultConfig: { ... ndk { abiFilters "armeabi", "armeabi-v7a", "x86", "mips" } }

  2. gradle.properties 中添加 android.useDeprecatedNdk=true

  3. 在 libs 下添加名为 armeabi 的新文件夹,然后将一个32位的.so文件复制到新文件夹中。

1
这对我来说足以防止崩溃发生 ndk { abiFilters "armeabi-v7a", "x86" } - Mark O'Sullivan
2
我可以从哪里下载32位的.so文件? - Avinash Shinde
2
安卓在2019年8月之后是否会阻止此解决方法,因为它需要完全支持64位? - manjunath kallannavar
4
从2019年8月1日起,根据谷歌政策规定,我们必须遵循64位指南。通过执行上述步骤,Play商店会显示警告。 - Tarun
是的,这也会在应用更新或发布新应用时在Play商店中显示错误。 - Sanket Sangani
显示剩余2条评论

4
这对我有用:
 ndk {
        abiFilters 'armeabi-v7a', 'x86'
    }

1
哦,你是救命恩人伙计 :) 非常感谢你。 - iamkdblue
这对我有用: ndk { abiFilters "armeabi", "armeabi-v7a", "x86", "mips" } - Nabzi
1
这个可以运行,但请记住,当您上传您的.apk或App bundle时,Google Play Store将强制您支持64位架构,并且您将被迫添加回abiFilters变体,问题也会再次出现。 - Antares
那么,上传Playstore的解决方案是什么? - Mani

1

0

实际上,它并没有说类似这样的话:“在与本地代码交互时,大多数情况下您不需要担心这个问题”。阅读完那段文字后,我最不希望看到的就是 UnsatisfiedLinkError。 - G B
你可能是对的,但我曾经遇到过与你完全相同的问题时出现了“UnsatisfiedLinkError”。如果我错了,抱歉。希望有人能更好地帮助你。 - shkschneider

0

我遇到了同样的问题,当我从Android Studio 2.1更新到2.2.3(使用ndk v.13.1)时,谷歌上没有找到真正帮助我的提示(例如使用abiFilters,排除'lib / x86_64 / lib… .so',LOCAL_MULTILIB:= 32或TARGET_PREFER_32_BIT:= true等)。

最终,我能够再次使用最新的AS v2.2.3使其正常工作(在Android.mk或build.gradle中未更改任何内容),只需使用以前的ndk编译器即android-ndk-r10e

我手动使用ndk-build仅为“armeabi-v7a”和“x86”构建了库,它在带有arm64的Android上完美运行。


0
对我来说,问题在于我在应用程序的构建设置中启用了高级分析功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接