Android APK包体积瘦身实战方案

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

二、代码瘦身方案

1、ReDex 进行分包优化、去除 debug 信息及行号信息(目前只支持mac liunx系统)

2、代码混淆(R8 & ProGuard)

3、三方库处理

去除重复功能的库,有些库如果只是调用里面小小部分代码,可以抽取出来。使用第三方库的时候要考虑大小

4、移除无用资源

APK 的资源主要包括图片、XML,与冗余代码一样,它也可能遗留了很多旧版本当中使用而新版本中不使用的资源,这点在快速开发的 App 中更可能出现。我们可以通过点击右键,选中 Refactor,然后点击 Remove Unused Resource => preview 可以预览找到的无用资源,点击 Do Refactor 可以去除冗余资源。如下图所示:

image_1arni457b1j7o1q3pu6f1gn62ju4b.png-57.2kB

5、使用Lint移除无效代码

步骤:点击菜单栏 Analyze -> Run Inspection by Name -> unused declaration -> Moudule ‘app’ -> OK

6、利用 ByteX Gradle 插件平台中的代码优化插件(少了0.2MB)

ByteX:https://github.com/bytedance/ByteX

如果你想在项目的编译阶段去除 access 方法,这里我更加建议直接使用 ByteXaccess_inline 插件。除了 access_inlie 之外,在 ByteX 中还有 四个 很实用的代码优化 Gradle 插件可以帮助我们有效减小 Dex 文件的大小,如下所示:

三、资源瘦身方案

1、图片压缩 png图片压缩(as插件tinyPNG),再png转webp格式(插件WebpConvert_Gradle_Plugin

2、资源压缩(AndroidResGuard)微信团队开源了一个资源混淆工具,AndResGuardhttps://github.com/shwenzhang/AndResGuard/blob/master/README.zh-cn.md)。它将资源的名称进行了混淆,所以可以用它对resources.arsc进行优化,只是具体优化效果与编码方式、id数量、平均减少命名长度有关。

3、资源文件最少化配置,大部分应用其实并不需要支持几十种语言的,微信也做了根据地区选择性下载语言包的功能。作为国内应用,我们可以只支持中文。这样在打包的时候就会排除私有项目、android系统库和第三方库中非中文的资源文件了,效果还是比较显著的。推荐在项目的build.gradle中进行如下配置:

android {
    ...
    defaultConfig {
	    ...
        //去除无用的语言,在鄙人项目中,差不多少了1MB
        resConfigs "zh", "zh-rCN"
        
        //这种虽然只配置armeabi 也是可以用,但是性能有损耗,项目减少3MB
        ndk {
           abiFilters "armeabi"
        }
    }
    ...
}    

4、资源在线,有些大的资源放在服务器; 每张图片尽量只保存一份;定统一的 字体、尺寸、颜色和按钮按压效果、分割线 shape、selector 背景。

5、删除无用字体、压缩(FontZiphttps://github.com/forJrking/FontZip

四、其他的方案

插件化 (每一个功能都是一个插件,并且都是可以从服务器下发下来的,那 App 的包体积肯定会小很多)

业务梳理(评估并删除无用或者低价值的业务)

转变开发模式(H5、小程序)

 

原文:

https://juejin.cn/post/6844904103131234311(上)

https://juejin.im/post/6872920643797680136#heading-12(下)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值