深入探索 Android 包体积优化(匠心制作一)

本文来自jsonchao的投稿,个人微信:bcce5360     

包体积优化能够给我们带来哪些 收益 呢?如何全面对应用的包体积进行 系统分析 及 针对性优化 呢?在这篇文章中,我们将一起进行深入地分析与探索。

思维导图大纲

目录

  • 一、瘦身优化及 Apk 分析方案

    • 1、瘦身优势

    • 2、APK 组成

    • 3、APK 分析

  • 二、代码瘦身方案探索

    • 1、Dex 探秘

    • 2、ProGuard

    • 3、D8 与 R8 优化

    • 4、去除 debug 信息与行号信息

    • 5、dex 分包优化

    • 6、使用 XZ Utils 进行 Dex 压缩

    • 7、三方库处理

    • 8、移除无用代码

    • 9、避免产生 Java access 方法

    • 10、利用 ByteX Gradle 插件平台中的代码优化插件

    • 11、小结

  • 三、资源瘦身方案探索

    • 1、冗余资源优化

    • 2、重复资源优化

    • 3、图片压缩

    • 4、使用针对性的图片格式

    • 5、资源混淆

    • 6、R Field 的内联优化

    • 7、资源合并方案

    • 8、资源文件最少化配置

    • 9、尽量每张图片只保留一份

    • 10、资源在线化

    • 11、统一应用风格

  • 四、So 瘦身方案探索

    • 1、So 移除方案

    • 2、So 移除方案优化版

    • 3、使用 XZ Utils 对 Native Library 进行压缩

    • 4、对 Native Library 进行合并

    • 5、删除 Native Library 中无用的导出 symbol

    • 6、So 动态下载

  • 五、其它优化方案

    • 1、插件化

    • 2、业务梳理

    • 3、转变开发模式

  • 六、包体积监控

    • 1、包体积监控的纬度

  • 七、瘦身优化常见问题

    • 1、怎么降低 Apk 包大小?

    • 2、Apk 瘦身如何实现长效治理?

  • 八、总结

下面,我们就先来了解下为什么要进行瘦身优化以及如何对 Apk 大小进行分析。

一、瘦身优化及 Apk 分析方案介绍

1、瘦身优势

主要有 三个方面 的原因:

1、下载转化率

       APK 瘦身优化在实际的项目中优先级是比较低的,因为做了之后它的好处不是那么明显,尤其是那些还没有到 稳定期 的项目,我们都知道,App 的发展历程是从 项目初期 => 成长期 => 稳定期,对于处于 发展初期与成长期 的项目而言,可能会做 启动优化、卡顿优化,但是一般不会做 瘦身优化瘦身优化 最主要的好处是对应用 下载转化率 的影响,它是 App 业务运营的重要指标之一,在项目精细化运营的阶段是非常重要的。因为如果你的 App 与其它同类型的 App 相比 Apk 体积要更小的话,那么你的 App 下载率就可能要高一些。而且,包体积越小,用户下载等待的时间也会越短,所以下载转换成功率也就越高。所以,安装包大小与下载转化率的关系 大致是成反比 的,即安装包越大,下载转换率就越小。一个 80MB 的应用,用户即使点了下载,也可能因为网络速度慢、突然反悔导致下载失败。而对于一个 20MB 的应用,用户点了下载之后,在犹豫要不要下的时候可能就已经下载完了。

而且,现在很多大型的 App 一般都会有一个 Lite 版本的 App,这个也是出于下载转化率方面的考虑。

2、应用市场

       Google Play 应用市场强制要求超过 100MB 的应用只能使用 APK  扩展文件方式 上传。当使用 APK 扩展文件方式 上传时,Google Play 会为我们的应用 托管 扩展文件,并将其 免费提供 给设备。扩展文件将保存到设备的共享存储位置(SD 卡或可安装 USB 的分区;也称为“外部”存储),应用可以在其中访问它们。在大多数设备上,Google Play 会在下载 APK 的同时下载扩展文件,因此应用在用户首次打开时便拥有了所需的一切。但是,在某些情况下,我们的应用必须在应用启动时从 Google Play 下载文件。如果您想避免使用扩展文件,并且想要应用程序的下载大小大于100 MB,则应该使用  Android App Bundles 上传应用程序,此时应用程序最多可提供150 MB的压缩下载大小Android App Bundles 就是 Android 应用程序捆绑包,它能够让 App添加动态功能模块的方式 去解决 APK 大小较大的问题。如下,就是由一个基本模块和两个动态功能模块组成的 Android App Bundle APK 的组成结构图:

3、渠道合作商的要求

       此外,还有一个原因,当我们的 App 做大之后,可能需要跟各个手机厂商合作预装,这些 渠道合作商会对你的 App 做详细的要求,只有达到相应的要求后才允许你的 App 预装到手机上。而且,越大的 App 其单价成本也会越高。所以,瘦身也是我们项目做大之后一定会遇到的一个问题。

体积过大对 App 性能的影响

此外,包体积除了会影响 应用的下载转化率 之外,主要还会对 App 三个方面 的性能有一定的影响,如下所示:

  • 1、安装时间:比如 文件拷贝、Library 解压,并且,在编译 ODEX 的时候,特别是对于 Android 5.0 和 6.0 系统来说,耗费的时间比较久,而 Android 7.0 之后有了 混合编译,所以还可以接受。最后,App 变大后,其 签名校验 的时间也会变长

  • 2、运行时内存:Resource 资源、Library 以及 Dex 类加载都会占用应用的一部分内存

  • 3、ROM 空间:如果应用的安装包大小为 50MB,那么启动解压之后很可能就已经超过 100MB 了。并且,如果 闪存空间不足,很可能出现“写入放大”的情况,它是闪存和固态硬盘(SSD)中一种不良的现象,闪存在可重新写入数据前必须先擦除,而擦除操作的粒度与写入操作相比低得多,执行这些操作就会多次移动(或改写)用户数据和元数据。因此,要改写数据,就需要读取闪存某些已使用的部分,更新它们,并写入到新的位置,如果新位置在之前已被使用过,还需连同先擦除;由于闪存的这种工作方式,必须擦除改写的闪存部分比新数据实际需要的大得多。即最终可能导致实际写入的物理资料量是写入资料量的多倍

2、APK 组成

       我们都知道,Android 项目最终会编译成一个 .apk 后缀的文件,实际上它就是一个 压缩包。因此,它内部还有很多不同类型的文件,这些文件,按照大小,共分为如下几类:

  • 1)、代码相关classes.dex,我们在项目中所编写的 java 文件,经过编译之后会生成一个 .class 文件,而这些所有的 .class 文件呢,它最终会经过 dx 工具编译生成一个 classes.dex

  • 2)、资源相关resassets、编译后的二进制资源文件 resources.arsc 和 清单文件 等等。resassets 的不同在于 res 目录下的文件会在 .R 文件中生成对应的资源 ID,而 assets 不会自动生成对应的 ID,而是通过 AssetManager 类的接口来获取。此外,每当在 res 文件夹下放一个文件时,aapt 就会自动生成对应 id 并保存在 .R 文件中,但 .R 文件仅仅只是保证编译程序不会报错,实际上在应用运行时,系统会根据 ID 寻找对应的资源路径,而 resources.arsc 文件就是用来记录这些 ID 和 资源文件位置对应关系 的文件

  • 3)、So 相关lib 目录下的文件,这块文件的优化空间其实非常大。

此外,还有 META-INF,它存放了应用的 签名信息,其中主要有 3个文件,如下所示:

  • 1)、MANIFEST.MF:其中每一个资源文件都有一个对应的 SHA-256-Digest(SHA1) 签名,MANIFEST.MF 文件的 SHA256(SHA1) 经过 base64 编码的结果即为 CERT.SF 中的 SHA256(SHA1)-Digest-Manifest 值。

  • 2)、CERT.SF:除了开头处定义的 SHA256(SHA1)-Digest-Manifest 值,后面几项的值是对 MANIFEST.MF 文件中的每项再次 SHA256(SHA1) 经过 base64 编码后的值。

  • 3)、CERT.RSA:其中包含了公钥、加密算法等信息。首先,对前一步生成的MANIFEST.MF使用了SHA256(SHA1)-RSA算法,用开发者私钥签名。然后,在安装时使用公钥解密。最后,将其与未加密的摘要信息(MANIFEST.MF文件)进行对比,如果相符,则表明内容没有被修改。

3、APK分析

下面,我们就来学习 APK 分析的 四种常用方式

1、使用 ApkTool 反编译工具分析 APK

     第一种方式,就是使用 ApkTool 这个反编译工具,它的官网地址如下:

ApkTool 官方网站https://github.com/iBotPeaches/Apktool

其具体的 反编译命令 如下所示:

apktool d xxx.apk

下面,我们就来使用 ApkTool 来对应用进行反编译。

ApkTool反编译实战
1、下载并配置apktool

apktool 下载配置官方文档https://www.jianshu.com/go-wild?ac=2&url=https%3A%2F%2Fibotpeaches.github.io%2FApktool%2Finstall%2F

我这里仅介绍 Mac OS X 平台上的下载配置,其它平台请点击上方链接查看。

  • 1)、下载脚本,保存为 apktool 文件。(https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/osx/apktool)

  • 2)、下载最新版 apktool.jar(需要翻墙https://bitbucket.org/iBotPeaches/apktool/downloads/)

  • 3)、将下载的 jar 包重命名为 apktool.jar

  • 4)、配置环境变量,这里有两种方案,如下所示:

    • 第一种是直接将 apktoolapktool.jar 移到 /usr/local/bin 目录,但是这里需要 root 权限,命令前加 sudo,回车后输入密码即可。

    • 第二种是在 ~/.bash_profile 文件下配置,首先新建 apktool 文件夹,将两个文件放到这个文件下,打开终端,使用 vim 加上环境配置,其命令如下所示:

   
 // 1、使用vim命令在命令行打开.bash_profile文件,并可以在命令行
    // 上编辑,当然,你也可以直接打开.bash_profile文件
    vim ~/.bash_profile
    // 2、在.bash_profile最后加上这一行即可
    export PATH=前面路径/apktool:$PATH
    // 3、使编辑后的配置生效
    source ~/.bash_profile
  • 5)、最后,使用以下命令将两个文件权限设置为 可执行 即可:

    sudo chmod a+x file

2、使用ApkTool分析APK

我们在命令行下输入以下命令对 APK 进行反编译,如下所示:

java -jar apktool_2.3.4.jar apktool d app-release.apk

反编译完成之后,它就会在当前的文件夹下面生成 app-release 的目录,目录结构如下所示:

这样我们就可以看到当前 App的具体组成 了。下面,我们介绍下第二种 APK 分析 的方式。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值