最近在研究APP瘦身,碰巧又遇到armeabi、armeabi-v7a、arm64-v8a等ABI相关的知识点,决心记录下来以作分享。
目前现状
首先我们分析下国内的淘宝、微信,以及国外的Facebook、Twitter都使用了哪些ABI。
我们对这4家APK进行Analyze,可以发现Facebook和Twitter只使用了armeabi-v7a,而微信和淘宝只使用了armeabi,分析结果如下图所示:
大厂并没有按照我们的理解使用不同的ABI针对不同的CPU?其实笔者发现携程、饿了么、百度糯米都是只使用了armeabi,阿里系的淘票票使用了armeabi、x86(如果你有兴趣,可以通过爬取分析一下应用市场的前100名都使用了哪些ABI)。
知识点回顾
首先,我们来看下Google老大哥是怎么介绍的ABI的,翻译官方文档:
不同 Android 手机使用不同的 CPU,因此支持不同的指令集
CPU 与指令集的每种组合都有其自己的应用二进制界面(或 ABI)
ABI 可以非常精确地定义应用的机器代码在运行时如何与系统交互
您必须为应用要使用的每个 CPU 架构指定 ABI
表 1. ABI 和支持的指令集。
各版本分析如下:
- mips / mips64: 极少用于手机可以忽
- x86 / x86_64: x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具,实现对 arm .so 的兼容,再考虑 x86 1% 以下的市场占有率,x86 相关的两个 .so 也是可以忽略的
- armeabi: ARM v5 这是相当老旧的一个版本,缺少对浮点数计算的硬件支持,在需要大量计算时有性能瓶颈
- armeabi-v7a: ARM v7 目前主流版本
- arm64-v8a: 64位支持
具体含义
如果你基础比较好的话,看完Google老大哥的介绍的话,就明白了:不同的 CPU 支持不同的指令集。当我们需要我们APP支持尽可能多的不同CPU的时候,只需要将不同版本的so文件放置在不同的目录下,APK安装运行的时候会根据自己需要而自己选取。
但是这样却带来一个问题,APK文件较大,影响用户下载。
那我们是否可以只放置一些呢?
必然可以!
我们继续看Google老大哥是怎么说的:
- 为实现最佳性能,应直接针对主要 ABI进行编译。例如,基于 ARMv5TE的典型设备只会定义主要 ABI:armeabi
- 相反,基于ARMv7的典型设备将主要ABI定义为armeabi-v7a,而将辅助ABI定义为armeabi,因为它可以运行为每个ABI生成的应用原生二进制文件
- 许多基于x86的设备也可行 armeabi-v7a 和 armeabi NDK 二进制文件
- 对于这些设备,主要ABI将是 x86,辅助ABI是armeabi-v7a
- 基于 MIPS的典型设备只定义主要ABI:mips
安装应用时,软件包管理器服务将扫描APK,查找以下形式的任何共享库:
12 > lib/<primary-abi>/lib<name>.so>如果未找到,并且您已定义辅助 ABI,该服务将扫描以下形式的共享库:
12 > lib/<secondary-abi>/lib<name>.so>找到所需的库时,软件包管理器会将它们复制到应用的 data 目录 (data/data/
/lib/) 下的/lib/lib .so
分析
上面说,如果根本没有共享对象文件,应用也会构建并安装,但在运行时会崩溃。所以有时候我们遇到
总结
如果你希望APK针对不同CPU有不同的版本,你可以使用胖二进制的方式,在不同的目录下面放置不同的so文件。这样兼容性更广、性能好些,但是APK大些;
如果你希望APK小一些,你可以像淘宝、微信、FaceBook、Twitter一样,一个api闯天下,至于选择armeabi、armeabi-v7a看你市场用户了。目前主流手机cpu多属于armeabi-v7a;
当然,你也可以动态检查系统环境,如果是x86就去下载相关库,然后加载……这样可以减少apk体积。
作者:微信公众号添加公众号-遛狗的程序员 ,或者可以扫描以下二维码关注相关技术文章。
当然喜爱技术,乐于分享的你也可以可以添加作者微信号: