总第513篇
2022年 第030篇
减小应用安装包的体积,对提升用户体验和下载转化率都大有益处。本文将结合美团平台的实践经验,分享 so 体积优化的思路、收益,以及工程实践中的注意事项。本文将先从 so 文件格式讲起,结合文件格式分析哪些内容可以优化,然后再具体讲解每项优化手段以及注意事项,最后介绍相关的工程实践经验。希望能对从事包体积优化的同学有所帮助或启发。
- 1. 背景
- 2. so 文件格式分析
- 3. so 可优化内容分析
- 4. 优化方案介绍
- 4.1 精简动态符号表
- 4.2 移除无用代码
- 4.3 优化指令长度
- 4.4 其他措施
- 4.5 整合后的通用方案
- 5. 工程实践
- 支持多种构建工具
- 配置导出符号的注意事项
- 查看优化后 so 的导出符号
- 解析崩溃堆栈
- 6. 方案收益
- 7. 总结与规划
1. 背景
应用安装包的体积影响着用户的下载时长、安装时长、磁盘占用空间等诸多方面,因此减小安装包的体积对于提升用户体验和下载转化率都大有益处。Android 应用安装包其实是一个 zip 文件,主要由 dex、assets、resource、so 等各类型文件压缩而成。目前业内常见的包体积优化方案大体分为以下几类:
- 针对 dex 的优化,例如 Proguard、dex 的 DebugItem 删除、字节码优化等;
- 针对 resource 的优化,例如 AndResGuard、webp 优化等;
- 针对 assets 的优化,例如压缩、动态下发等;
- 针对 so 的优化,同 assets,另外还有移除调试符号等。
随着动态化、端智能等技术的广泛应用,在采用上述优化手段后, so 在安装包体积中的比重依然很高,我们开始思索这部分体积是否能进一步优化。
经过一段时间的调研、分析和验证,我们逐渐摸索出一套可以将应用安装包中 so 体积进一步减小 30%~60% 的方案。该方案包含一系列纯技术优化手段,对业务侵入性低,通过简单的配置,可以快速部署生效,目前美团 App 已在线上部署使用。为让大家能知其然,也能知其所以然,本文将先从 so 文件格式讲起,结合文件格式分析哪些内容可以优化。
2. so 文件格式分析
so 即动态库,本质上是 ELF(Executable and Linkable Format)文件。可以从两个维度查看 so 文件的内部结构:链接视图(Linking View)和执行视图(Execution View)。链接视图将 so 主体看作多个 section 的组合,该视图体现的是 so 是如何组装的,是编译链接的视角。而执行视图将 so 主体看作多个 segment 的组合,该视图告诉动态链接器如何加载和执行该 so,是运行时的视角。鉴于对 so 优化更侧重于编译链接角度,并且通常一个 segment 包含多个 section(即链接视图对 so 的分解粒度更小),因此我们这里只讨论 so 的链接视图。
通过 readelf -S
命令可以查看一个 so 文件的所有 section 列表,参考 ELF 文件格式说明,这里简要介绍一下本文涉及的 section:
.text
:存放的是编译后的机器指令,C/C 代码的大部分函数编译后就存放在这里。这里只有机器指令,没有字符串等信息。.data
:存放的是初始值不为零的一些可读写变量。.bss
:存放的是初始值为零或未初始化的一些可读写变量。该 section 仅指示运行时需要的内存大小,不会占用 so 文件的体积。.rodata
:存放的是一些只读常量。.dynsym
:动态符号表,给出了该 so 对外提供的符号(导出符号)和依赖外部的符号(导入符号)的信息。.dynstr
:字符串池,不同字符串以 '