抖音 Android 包体积优化探索:资源二进制格式的极致精简

动手点关注 干货不迷路 👆

前言

目前,安卓端对于包体积的优化方案已经多如过江之鲫,我们系列的上一篇文章介绍了 Class 字节码的优化,本期我们将关注点聚焦到资源文件上,从资源二进制文件的全新角度,拓展出包体积优化的新思路。

在资源文件优化方面,通常的优化手段多集中在图片/文件压缩、资源文件名称混淆、离线下载资源文件等方面,而我们的新思路基于对于常规思路的深度分析及思考。

一开始,我们是从资源文件名称混淆入手优化,业界对于资源文件名称混淆方案,最为熟知的开源项目当属 AndResGuard,该项目优化目标为资源文件目录 res 内的文件,其优化点如下:

  1. 对重复的资源文件,以计算 md5 值的方式来判断是否重复并只保留一份;

  2. 对资源文件名称进行缩短,即名称混淆;

  3. 对 APK 中的内容采取 7zip 压缩优化;

按照此项目进行优化,总体收益可以达到非常可观的 MB 级别。但完成此项目的优化后,资源文件的进一步优化便达到瓶颈。

为了在此基础上更好的实现优化资源大小,我们需要了解资源文件目录 res 所包含的文件类型及其大小的分布情况。以抖音为例,下表是对其包含的子文件夹名称、文件数量、将文件夹 zip 压缩后大小的梳理,以文件数量降序排序:

子文件夹名称
文件数量 文件夹zip压缩后大小
drawable-xxhdpi-v4 6054 19.5MB
layout 5970 12.2MB
drawable
4388 4.6MB
layout-v17 2985 8.5MB
drawable-night-xxhdpi-v8 994 ...
drawable-xhdpi-v4 431 ...
anim 382 ...
color 152 ...

从上表,可以看到:

  • drawable-xxhdpi-v4 目录下文件数量最多有 6000+,压缩后文件大小约为 19.5MB。

  • drawable 目录下文件数量排第三,有 4388 个,压缩后 4.6MB,同时包含图片和.xml 文件。

  • 文件数量排第二和第四的都是 layout 目录下的布局文件,分别有 5970,2985 个,其文件夹压缩后大小分别为 12.2MB,8.5MB。布局文件总数近 9K,文件大小约 20.7MB

可见,layout 目录下的布局文件大小已经和图片文件不相上下。而这部分如此大的文件,除了有文件名称的混淆优化之外,是否还有其他优化方式?或者其文件名称混淆是否彻底?

此外,APK 解压后的 resources.arsc 文件有 7.3MB 之大。其中包含了 app 所有资源文件名称和资源字符串值,其中是否也存在冗余字符串?

对于 layout 布局文件,从近万份之多的文件数量及 20+MB 的文件体积来看,即存在值得探究的必要。我们通过对资源文件的二进制文件格式的解析,并从文件内容被使用的角度分析,发现存在可以删除的冗余内容。在反复尝试并解决了各种稳定性和打包兼容问题后,最终研发出了一套针对 Android ARSC/XML 文件格式的包体积优化方案,目前已经落地抖音,实现 2MB 以上的收益。

接下来,本文将深入讲解该方案的实现细节。

APK 资源格式优化

我们的核心思路是,以资源路径缩短为优化出发点,在最终的 APK 文件里,从resources.arsc与 layout 布局文件的二进制文件格式着手,查看其内容结构,寻找可以删除的未使用字符串,优化文件名称或者文件里的字符串池。主要分为下面两个优化点。

资源路径缩短

资源格式修改

接入 AndResGuard 后,资源文件 res 目录 -> r,其中的子文件夹和文件名也都被混淆,即:

  • res/anim/abc_fade_in.xml -> r/a/a.xml

这是为了减少资源文件路径,从而减少包体积,自然联想到,是否还能进一步减少资源文件路径呢?显然,如果能将所有文件都放在 r 目录下,将中间的子文件夹去掉,则可以进一步减少资源文件路径和 zip 节点数量,一定还有包体收益;顺便可以将文件名的后缀去掉,也可以减少文件路径,即:

  • r/a/a.xml -> r/a

  • r/a/b.png -> r/b

1cf13c48b0691fdbe25b70ef07c18cd3.png

由于修改资源文件名称需要修改resources.arsc文件,这里对resources.arsc 的文件格式分析下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值