defaultConfig {
ndk {
abiFilters ‘arm64-v8a’, ‘x86_64’
}
}
}
你可能看了上面的这些文字,还不能理解abi的作用,那么我们就用一个简单的例子来说明一下。
2.1 举例说明ABI的作用
首先,我们创建一个最简单的Hello world
应用,只有一个Activity和一个启动图标。我们看以下打出来的apk:
没有任何的原生库使用,大小为2.1MB
,现在我们为它添加多ABI原生库支持,我们在项目中集成Realm
,然后打包。
看到没,apk大小从2.1MB
猛增加到11.2MB
,多了一个原生so库的文件夹,大小为8.8MB
,我们来看一下它的详细信息:
如上图所示,Realm
为5种CPU架构生成了.so
库,分别是mips
、x86
、x86_64
、arm64-v8a
、armeabi-v7a
。增加了8.8MB
包的大小。但是这不是我们想要的,我们只想要适配我们指定的的CPU架构,因此,我们需要在gralde.build中添加abifilters
配置来完成我们想要的效果:
android {
compileSdkVersion 28 // 编译sdk版本
defaultConfig {
applicationId “com.example.zhouwei.helloworld”
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName “1.0”
testInstrumentationRunner “android.support.test.runner.AndroidJUnitRunner”
// 适配指定CPU架构
ndk {
abiFilters ‘arm64-v8a’, ‘x86_64’
}
}
}
效果如下:
可以看到,只生成了我们指定CPU架构的so文件,包的大小也减少了5.3MB
。
这时候,你可能会有一个疑问,Android 共支持7种CPU架构,那么,我们在实际项目中该适配哪些CPU架构能保证最好的兼容,同时又最大限度的减少APK的大小?
在回答这个问题之前,我们不妨看一下这些顶级巨头公司,他们是是如何适配的。
3. 目前大厂APP是如何适配不同的CPU架构的?
首先,我们下载一些大厂的APK,看一下他们的适配情况,这里我分析了微信、手机QQ、支付宝和淘宝这4个APP的适配情况:
可以看到,微信适配的是arm64-v8a
(微信应该是最近才适配到arm64-v8a
,以前是armeabi
),支付宝和手Q适配的是armwabi
,淘宝适配的是armwabi-v7a
。各个APP适配的平台不太一样,但是他们有一个共同点,那就是它们只指定了一个平台。
等等,上面这些APP只适配了一中CPU架构,比如只适配了armwabi-v7a
,那如果APP装在其他架构的手机上,如arm64-v8a
上,会蹦吗?
要弄清楚这个问题,我们得先搞清楚,ABI是如何工作的。
ABI是如何工作的呢?
官方文档解释如下:
Android 系统在运行时知道它支持哪些 ABI,因为版本特定的系统属性会指示:
- 设备的主要 ABI,与系统映像本身使用的机器代码对应。
- (可选)与系统映像也支持的其他 ABI 对应的辅助 ABI。
此机制确保系统在安装时从软件包提取最佳机器代码。
为实现最佳性能,应直接针对主要 ABI 进行编译。例如,基于 ARMv5TE 的典型设备只会定义主 ABI:armeabi。相反,基于 ARMv7 的典型设备将主 ABI 定义为 armeabi-v7a,并将辅助 ABI 定义为 armeabi,因为它可以运行为每个 ABI 生成的应用原生二进制文件。
64 位设备也支持其 32 位变体。以 arm64-v8a 设备为例,该设备也可以运行 armeabi 和 armeabi-v7a 代码。但请注意,如果应用以 arm64-v8a 为目标,而非依赖于运行 armeabi-v7a 版应用的设备,则应用在 64 位设备上的性能要好得多。
许多基于 x86 的设备也可运行 armeabi-v7a 和 armeabi NDK 二进制文件。对于这些设备,主 ABI 将是 x86,辅助 ABI 是 armeabi-v7a。
上面这一段是不是有点看蒙了,这里我来简单解释以下。总的来说,就是一个Android设备可以支持多种ABI,设备主ABI和辅助ABI,以arm64-v8a
为主ABI的设备,辅助ABI为armeabi-v7a
和armeabi
,以armeabi-v7a
为主ABI的设备,辅助ABI为armeabi
。
另外,x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现对 arm .so 的兼容,也就是说有适配armeabi平台的APP是可以跑在x86手机上的。
3.1 主辅助ABI具体适配流程
前面说了ABI的工作原理,一个Android设备支持主辅ABI,那么他们具体是如何工作的呢?我们以arm64-v8a
架构的手机为例:
对于一个cpu是arm64-v8a架构的手机,它运行app时,进入jnilibs去读取库文件时,先看有没有arm64-v8a文件夹,如果没有该文件夹,去找armeabi-v7a文件夹,如果没有,再去找armeabi文件夹,如果连这个文件夹也没有,就抛出异常;
如果有arm64-v8a文件夹,那么就去找特定名称的.so文件,注意:如果没有找到想要的.so
文件,不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常。
Exception:Java.lang.UnsatisfiedLinkError: dlopen failed: library “/***.so” not found
特别需要注意的情况是在命中了文件夹,而未命中so文件这种情况:
-
比如命中了
arm64-v8a
文件夹,没有找到需要的so文件,就不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常。 -
如果你的项目用到了第三方依赖,如果只保留一个ABI的时候,建议在Build中加入ndk.abiFilters
-
例如:第三方aar文件,如果这个sdk对abi的支持比较全,可能会包含armeabi、armeabi-v7a、x86、arm64-v8a、x86_64五种abi,而你应用的其它so只支持armeabi、armeabi-v7a、x86三种,直接引用sdk的aar,会自动编译出支持5种abi的包。但是应用的其它so缺少对其它两种abi的支持,那么如果应用运行于arm64-v8a、x86_64为首选abi的设备上时,就会crash了哦。
因此,我们需要在我们的app中配置 abiFilter 配置,来避免一些未知的错误。
defaultConfig {
ndk {
abiFilters “armeabi”// 指定ndk需要兼容的ABI(这样其他依赖包里x86,armeabi,arm-v8之类的so会被过滤掉)
}
}
3.2 Android 7种CPU架构在当前市场的占有率
-
arm64-v8a
: 目前主流版本 -
armeabi-v7a
: 一些老旧的手机 -
x86 / x86_64
: x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现对 arm .so 的兼容,再考虑 x86 1% 以下的市场占有率,x86 相关的两个 .so 也是可以忽略的 -
armeabi/mips / mips64
: NDK 以前支持 ARMv5 (armeabi) 以及 32 位和 64 位 MIPS,但 NDK r17 已不再支持,极少用于手机可以忽。
目前手机市场上,x86 / x86_64/armeabi/mips / mips6
的架构,基本可以不不考虑了,它们的占有量应很少很少了,arm64-v8a
作为最新一代架构,应该是目前的主流,armeabi-v7a
只存在少部分老旧手机。
我试着在Google上查找,具体的市场占有数据,但没找到,但是从国民级应用微信只适配arm64-v8a
就可以看出,arm64-v8a
是目前的主流,并且还有一点,Google Play 从2019年8月开始,就强制APP适配arm64-v8a
,以慢慢淘汰32位的armeabi-v7a
。
4. 我们项目中该如何适配呢?
这里就可以回答前面的两个问题了。
Q1
: 只适配了armwabi-v7a
,那如果APP装在其他架构的手机上,如arm64-v8a
上,会蹦吗?
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
其他重要知识点
下面是有几位Android行业大佬对应上方技术点整理的一些进阶资料。有**【Android架构视频+BATJ面试专题PDF+核心笔记等资料+源码+思维导图】。希望能够帮助到大家提升技术。如果大家想要获取的话,可以私信我【666】免费获取哦~**
高级进阶篇——高级UI,自定义View(部分展示)
UI这块知识是现今使用者最多的。当年火爆一时的Android入门培训,学会这小块知识就能随便找到不错的工作了。不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!
- 面试题部分合集
培训,学会这小块知识就能随便找到不错的工作了。不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!
[外链图片转存中…(img-OXA73woD-1711355383278)]
- 面试题部分合集
[外链图片转存中…(img-fiqfKZfW-1711355383278)]