在Android上强制CPU/ABI使用armeabi-v7a

在Android上强制CPU/ABI使用armeabi-v7a,android,android-ndk,java-native-interface,arm,Android,Android Ndk,Java Native Interface,Arm,我有一个Android应用程序,它使用一些JNI代码。长话短说(双关语),将JNI库转换为64位几乎是不可能的,因为它需要很多更改。代码(Java和JNI)在armeabi-v7a体系结构上运行良好 正在使用loadLibrary加载库。当我尝试在Nexus 6上运行我的应用程序时,该应用程序可以正常加载。loadLibrary一执行,应用程序就会崩溃,并出现所述错误 据我所知,问题在于在Nexus6上执行时,应用程序构建为arm64-8a。但是这些库不是为arm64-8a构建的(因为64位版本

我有一个Android应用程序,它使用一些JNI代码。长话短说(双关语),将JNI库转换为64位几乎是不可能的,因为它需要很多更改。代码(Java和JNI)在armeabi-v7a体系结构上运行良好

正在使用loadLibrary加载库。当我尝试在Nexus 6上运行我的应用程序时,该应用程序可以正常加载。loadLibrary一执行,应用程序就会崩溃,并出现所述错误

据我所知,问题在于在Nexus6上执行时,应用程序构建为arm64-8a。但是这些库不是为arm64-8a构建的(因为64位版本有我在问题开始时提到的问题)


我的问题是,我可以强制arm64-8a设备也运行armeabi-v7a代码吗?如何强制我的应用程序apk为armeabi-v7a,使其仅为32位,而不考虑设备?

是的,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位


有关类似问题的答案,请参阅和。

谢谢您的回答。我认为有一个复杂性阻碍了您在第二段中所描述的内容-我定义了外部依赖项(特别是realm和amazonaws),它们似乎正在下载arm64-v8a。我将JNI库更改为.a文件,但不确定如何正确加载它。我能在有机会影响ABI选择之前强制加载我的库吗?依赖项在app build.gradle中定义,例如
编译'com.amazonaws:aws-android-sdk-s3:2.2.11'
加载库的实际顺序并不重要;重要的是APK中存在哪些不同的ABI目录。如果其中一个依赖项包含
arm64-v8a
,则此目录将在APK中结束,APK安装程序将选择此体系结构。尝试查看您构建的APK(
unzip-l filename.APK
),并查看它包含哪些体系结构目录。不过,您可以做的是过滤掉实际包含的ABI;尝试在你的gradle文件中添加
abiFilters'armeabi-v7a'
,使其仅包含此单一体系结构。我将你的答案标记为正确,因为我能够验证当另一个64位库不存在时,应用程序默认为32位。在我的例子中,问题是由realm android引起的——我在应用程序和project build.gradle文件中都有条目来启用realm插件。这将强制加载arm64-v8a库。我会尝试abiFilters步骤,如果它有效的话,我会修改这个评论。据我所知,abiFilters的问题是它只适用于ndk步骤。我已经在Application.mk中定义了
APP_ABI:=armeabi-v7a
。我的问题与处的安装说明直接相关-此处建议对build.gradle文件进行的更改会覆盖NDK设置。不,abiFilters不仅适用于构建自己的本机代码的步骤,还适用于过滤掉通过依赖项隐式包含的不需要的体系结构。