我有一个使用一些JNI代码的Android应用。长话短说(双关语),几乎不可能将JNI库转换为64位,因为它需要进行大量更改。代码(Java和JNI)在armeabi-v7a架构上运行良好。
使用loadLibrary加载库。当我尝试在Nexus 6上运行我的应用程序时,应用程序加载正常。执行loadLibrary后,应用程序崩溃并显示here所述的错误。
根据我的理解,问题是在Nexus 6上执行时,应用程序构建为arm64-8a。但这些库不是为arm64-8a构建的(因为64位版本存在我在问题开头提到的问题)。
我的问题是,我可以强制arm64-8a设备运行armeabi-v7a代码吗?如何强制我的应用apk为armeabi-v7a所以它只是32位而不管设备?
答案 0 :(得分:13)
是的,arm64-v8a设备也可以运行armeabi-v7a代码。
安装APK后,安装程序会检查程序包是否包含官方目录中的库,并根据结果将活动标记为32位或64位。
如果它在APK中找到lib/arm64-v8a
中的库(通常取自构建目录中的目录libs/arm64-v8a
),它将被标记为64位,并将忽略所有其他目录。如果它在APK中找到lib/armeabi-v7a
或lib/armeabi
中的库,则该过程将标记为32位。如果其中任何一个都没有本机库,安装程序会假定应用程序根本不使用本机代码,并且可以在任何模式下自由运行它,实际上是64位模式。
现在,如果您在64位模式下运送一些但不是所有库,则该过程将以64位模式启动,并且无法加载32位库(甚至不会安装)。在这种情况下,您必须避免捆绑任何64位库,除非所有这些库都可用。
或者您不使用官方的libs目录,而是以其他方式安装库(例如,通过在运行时下载它们或将它们保存在例如资产中),系统不知道您的进程想要以32位运行库模式(此时切换到其他模式为时已晚)。在这些情况下,请确保以正常/官方方式包含至少一些虚拟库,以便将应用程序标记为32位。
有关类似问题的解答,请参阅https://stackoverflow.com/a/33919454/3115956,https://stackoverflow.com/a/27713998/3115956和https://stackoverflow.com/a/35450911/3115956。