原理
Android 系统本质是一个经过改造的 Linux 系统。最早,Android 系统只支持 ARMv5 的 CPU 构架,随着 Android 系统的发展,又加入了 ARMv7 (2010), x86 (2011), MIPS (2012), ARMv8, MIPS64 和 x86_64 (2014)。
每一种 CPU 构架,都定义了一种 ABI(Application Binary Interface),ABI 决定了二进制文件如何与系统进行交互。
ABI和CPU的关系
- 很多设备都支持多于一种的ABI。
- 当一个应用安装在设备上,只有该设备支持的CPU架构对应的.so文件会被安装。
但最好是针对特定平台提供相应平台的二进制包,这种情况下运行时就少了一个模拟层(例如x86设备上模拟arm的虚拟层),从而得到更好的性能(归功于最近的架构更新,例如硬件fpu,更多的寄存器,更好的向量化等)。
我们可以通过Build.SUPPORTED_ABIS得到根据偏好排序的设备支持的ABI列表。但你不应该从你的应用程序中读取它,因为Android包管理器安装APK时,会自动选择APK包中为对应系统ABI预编译好的.so文件,
ABI(横向)和cpu(纵向) | armeabi | armeabi-v7a | arm64-v8a | mips | mips64 | x86 | x86_64 |
---|---|---|---|---|---|---|---|
ARMv5 | 支持 | ||||||
ARMv7 | 支持 | 支持 | |||||
ARMv8 | 支持 | 支持 | 支持 | ||||
MIPS | 支持 | ||||||
MIPS64 | 支持 | 支持 | |||||
x86 | 支持(3) | 支持(2) | 支持(1) | ||||
x86_64 | 支持 | 支持 | 支持 |
不同的ABI,针对不同的cpu架构有不同的优先权
准则
NDK SO 开发者应该遵循一个准则:支持所有的平台,否则将会搞砸你的用户。
NDK SO 使用者应该遵循一个准则:要么支持所有平台,要么都不支持。
然而,事与愿违,因为种种原因(遗留 SO、芯片市场占有率、APK 包大小等),并不是所有人都遵循这样的原则。
Android Studio
- Android Gradle 插件中,可以使用如下方式对 abi 进行过滤:
android { ... defaultConfig { ... ndk { // 设置支持的 SO 库构架,注意这里要根据你的实际情况来设置 abiFilters 'armeabi'// 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64' } }}
关键行:
abiFilters 'armeabi'// 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64'
根据你的 APP 中使用的 SO 库所支持的构架具体情况,你可以进行具体设置。最终输出的 apk 中,将会包含你所选择的 abi。
像前面举出的例子,就应该只允许 armeabi。
- 如果在添加 “abiFilter” 之后 Android Studio 出现以下提示:
NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin
则在项目根目录的 gradle.properties 文件中添加:
android.useDeprecatedNdk=true