logo头像

我有一个梦想

包体积优化

本文于 909 天之前发表,文中内容可能已经过时。

[TOC]

优化好处

  1. 包体积减小,易于升级
  2. 多市场渠道有体积限制,避免二次处理
  3. apk安装时间减小
  4. 运行时内存占用小
  5. 磁盘空间占用小,odex二进制文件小。

APK组成及分析

APK组成

  • assets: 开发目录下assets目录
  • lib:所需要的so库
  • META-INF:签名文件
  • okhttp3:okhttp网络相关
  • org:org相关信息
  • res:布局信息,对应开发目录res下
  • AndroidManifest:四大组件配置
  • classes.dex:代码压缩文件

apk分析

  1. 使用常规apktool方法
  2. 使用jadx工具

    https://github.com/skylot/jadx

    直接将apk拖入程序即可查看各种信息

  3. Android Studio中的Analyze apk可以分析apk的组成

优化方案

代码优化

代码全部存储在dex文件中,所以我们需要先搞懂什么是dex?

dex理解

dex文件是专为Dalvik设计的一种压缩格式

.java–>.class–>.dex

在.java–>.class过程中,主要是jvm的操作,在.class–>.dex过程中,需要将.class文件转化为Dalvik识别的.dex文件

dex主要结构如下:

image

同jar相比,dex文件的大小能够缩减50%左右

ProGuard代码混淆

在build.gradle中开启混淆,将类名转化为没有意义的a,b,c等,提高阅读难度,其次通过缩短名称可以有效缩减dex大小,而且会移除在代码中没有使用的代码。

D8与R8的优化
  • D8:把java字节码转化为dex代码,简单来说就是dex编译器
  • R8:混淆压缩与优化部分的替代品,但是不能完全替代proguard

D8的提出是用来取代DX的,他的优化如下:

  • 编译时间缩短
  • .dex文件更小
  • .dex运行性能更好
  • 包含java8语言支持

R8与proguard非常相似,但不能完全替代proguard

  • ProGuard 在将枚举类型简化为原始整数方面会更加强大
  • ProGuard 中应用的模式匹配算法可以识别和替换短指令序列,从而提高代码效率并为更多优化打开了机会。在优化遍历的顺序中,尤其是数学运算和字符串运算可从中受益
  • ProGuard 具有独特的能力来优化使用 GSON 库将对象序列化或反序列化为 JSON 的代码
Dex分包优化

当apk方法数超过65536时,必须采用分包策略,这样跨dex调用会出现一些重复信息:

  • 多余的 method id:跨 Dex 调用会导致当前dex保留被调用dex中的方法id,这种冗余会导致每一个dex中可以存放的class变少,最终又会导致编译出来的dex数量增多,而dex数据的增加又会进一步加重这个问题。
  • 其它跨dex调用造成的信息冗余:除了需要多记录被调用的method id之外,还需多记录其所属类和当前方法的定义信息,这会造成 string_ids、type_ids、proto_ids 这几部分信息的冗余。

所以使用ReDex进行分包优化,同时,去除dex文件中的debug信息及行号信息

svg的使用

使用指定语言,删除不必要的语言

使用XZ Utils进行Dex压缩

https://tukaani.org/xz/
将dex压缩后放在assets目录中,减少包体积,但是会提高安装时间

三方库优化

在使用三方库中,小库可以完成目前业务就是用小库,减小三方库的大小,比如Picasso、Glide、Fresco的大小和功能

Lint

使用Lint优化代码,移除没有使用的代码

减少enum的使用

Android 中的 Enum 到底占多少内存?该如何用?

资源优化

  • Lint:使用lint去除冗余资源
  • shrinkResources:去除无用资源
  • 重复资源优化:多模块使用同一个资源文件,去除重复资源文件,保留第一份资源
  • 图片压缩:AAPT优化图片,选择webp格式的图片
  • 使用针对性图片格式
    1. 聊天表情出一套图 => hdpi。
    2. 纯色小 icon 使用 VD => raw。
    3. 背景大图出一套 => xhdpi。
    4. logo 等权重比较大的图片出两套 => hdpi,xhdpi。
    5. 若某些图在真机中有异常,则用多套图。
    6. 若遇到奇葩机型,则针对性补图。
  • 资源路径混淆成单个资源的路径:使用AndroidResGuard,缩短资源路径
  • 将资源文件放置在服务器上,通过网络加载

so库优化

  • 通过abiFilters过滤so库
  • 对于敏感的so库,不同架构全部放置在armeabi中,在程序中判断系统架构,加载不同的so库
  • Native Library压缩:XZ Utils,SoLoader
  • so库动态下载:https://mp.weixin.qq.com/s/X58fK02imnNkvUMFt23OAg

其他优化

  1. 插件化

    插件可以热插拔,从服务器下载

  2. 转变开发模式

    使用混合式开发

  3. 梳理业务,简化逻辑和业务