App体积优化

随着Android移动开发的需求越来越复杂,我们不可避免的遇到发布出去的apk体积越来越大的问题,
目前超过10MB、20MB的apk已经是很常见的事情了,但是依然能够看到一些apk的体积控制的很小。

apk体积增大源于:

新需求不断的提出
需要支持高分辨率的屏幕而加入了高分图片
依赖了更多的第三方库

其实优化主要是两块,dex和资源。

1.代码优化

  1. 使用lint或其他工具扫描无用代码。
  2. 使用开源库的时候综合分析,选择好的lib能够减少代码
  3. 使用ProGuard代码混淆,能够很大程度减小dex大小

2 资源优化

  1. lint扫描无用资源。
  2. 使用 shrinkResources true属性,这里shrinkResources属性的作用并不大,因为在扫描无用资源过程中, 系统为了避免使用getIdentifier过程找不到资源,所以在清除资源的时候条件判断非常严格,经过测试,这个功能非常鸡肋,大量无用的资源无法删除。
  3. 支持特定的分辨率。现在大部分手机都是1080p,对应的xxhdpi的资源,所以我们只支持xxhdpi的资源,其他屏幕即使大一点,图片放大也不会太模糊。
  4. 图片压缩。常规的png图片压缩,png转webp, 在转webp的时候注意最终的压缩大小,webp的一些压缩方式可能比png大。webp格式4.0+都支持,对于包含透明度的4.2+才支持。这里我们测试先对png压缩,在将压缩的png转webp,压缩效果更好。
  5. 使用矢量图。 这个在我项目中后面大量用到了,缺点就是对5.+的系统支持的比较好,低版本也有support库支持。

3 其他

3.1 微信AndResGuard

使用AndResGuard,体积能减少1-2M,而且能混淆资源。其原理和proguard类似,混淆路径,减小路径长度,最终减小arsc文件的大小;开启7zip压缩,对apk重新多重压缩。
坑:因为混淆资源路径,所以使用getIdentifier的方法是获取不到资源的。这里也是通过项目禁止使用getIdentifier方法获取资源。

3.2 使用redex

其实使用Redex比较简单,按照官网的来。我们遇到的问题是,去除单实现接口,这个选项我们关闭了,因为这个选项开启,需要改动较大,而且需要配置较多的白名单。其他没什么问题。
这块大小我测试,开启全部的选项,在去除无用代码和开启proguard后,,dex能缩小8%, 如果去除SingleImplPass的选项,大概只有3%。

4 遇到的问题

  1. 比如清除无用资源时候无法查找使用getIdentifier引用的资源,导致删除资源后闪退问题,所以我们直接在代码扫描规则中禁止使用getIdentifier这个方法。
  2. AndResGuard 因为混淆资源路径,所以使用getIdentifier的方法是获取不到资源的。这里也是通过项目禁止使用getIdentifier方法获取资源。
  3. 在使用矢量图的过程中,在部分系统控件闪退的问题。

5 维持

  1. 无用资源和代码我们qa有脚本定时扫描,能够很好的解决。
  2. 引入第三方lib需要组长审核。
  3. 图片压缩通过gradle插件执行。
  4. 集成微信apkcanary,输出每个版本apk文件大小及每个组成部分的大小,并生成html,保存这些文件,在后续的版本中对比。