android 混淆压缩比例,Android apk瘦身最佳实践(二):代码混淆和资源压缩

要尽可能减小 APK 文件,我们应该启用压缩来移除发布构建中未使用的代码和资源。

1. 使用 ProGuard 混淆代码

在 Android 中代码混淆和压缩都是通过 ProGuard 来实现的,ProGuard 会检测和移除代码中未使用的类、字段、方法和属性,除此外还可以优化字节码,移除未使用的代码指令,以及用短名称混淆类、字段和方法。

在 build.gradle 中,使用 minifyEnabled 属性来开启代码混淆:

android {

buildTypes {

release {

minifyEnabled true

proguardFiles getDefaultProguardFile('proguard-android.txt'),

'proguard-rules.pro'

}

}

...

}

2. 使用 shrinkResources 压缩资源

在 build.gradle 中使用 shrinkResources 属性来开启资源压缩,它在构建 apk 时可以移除那些没有引用到的资源文件,通常它必须与 minifyEnabled 属性一起使用:

release {

shrinkResources true

minifyEnabled true

proguardFiles getDefaultProguardFile('proguard-android.txt'),

'proguard-rules.pro'

}

需要注意的是,开启该属性设置后,它并不会移除 values/ 文件夹中定义的资源,例如:字符串、颜色、样式等等。

3. 混淆压缩对比

为了鉴定一下代码混淆与资源压缩到底有多大作用,我们随便找个简单的 app 工程来实验一下。

minifyEnabled

shrinkResources

apk大小

false

false

4,285,579 字节,约4.3M

true

false

3,781,347 字节,约3.8M

true

true

3,779,525 字节,约3.8M

false

true

无法编译

从中我们可以得到一些结论:

开启代码混淆和资源压缩后,apk 大小减少了约0.5M,一个小工程都尚且如此,在一个比较庞大的工程中开启这俩选项,压缩的大小还是很可观的。

开启资源压缩与不开启相比,只减少了约2000多字节的大小,可见大头还是靠代码混淆,资源压缩只能起到锦上添花的作用。

关闭代码混淆开启资源压缩,你会发现无法编译,Android Studio 会提示你这俩必须配对使用,要开启资源压缩必须得开启代码混淆。

4. 资源压缩会保留文件名不保留内容

我们再做个测试,在应用的资源中放一张png图片姑且命名为 test.png,放一个layout布局文件命名为test.xml,并且确保这2个资源文件没有任何代码会引用,我们开启代码混淆和资源压缩打包生成apk文件。

生成apk文件后,直接将apk包拖到 Android Studio 中,可以查看apk包的相关信息,细心一点的话你会发现几个有趣的现象:

在图片资源文件夹中,仍然可以看到名为 test.png 的图片,但是你打开看到的是一个 1*1 的图片;

在 layout 文件夹中,仍然可以看到名为 test.xml 的文件,打开看到的是一个空的xml文件,没有任何xml节点信息;

也就是说,资源压缩后,并不是直接删除了没有用到的资源文件,而是生成了对应的占位文件,这些占位文件都是空文件,相比原文件大小可以忽略不计。这样做的原因是:每个资源文件都对应 R.class 里的一个资源 id ,资源 id 的映射关系会打包在 resources.arsc 文件里,如果直接删除了资源文件,则可能需要同时修改 resources.arsc 里的资源映射表,这样是很繁琐的过程,而用占位文件来替换则避免了这种情况。

5. 使用 resConfigs 去除多余的语言包

目前很多第三方库内包含了各种语言包,但是大多数情况下我们的应用是不需要国际化,仅仅需要中文的就可以了,所以可以 resConfigs 配置来去掉多余的语言包:

android {

defaultConfig {

...

resConfigs "zh"

}

}

如上所示,打包时只会将中文的资源包打进去,这样也可以一定程度上减小 apk 的体积。

6. ProGuard 中的压缩优化配置

关于 ProGuard 的配置有很多,具体需要查看文档才能知道作用是什么。刚开始接触的时候,我以为 ProGuard 只是做代码混淆而用的,其实它的作用不仅仅如此,有2个配置我们经常会忽略掉:

-dontshrink

声明不进行压缩操作。

-dontoptimize

不对 class 进行优化,默认是开启优化的。由于优化会进行类合并、内联等,使用热修复的应用,建议关闭优化。

我发现很多第三方库,例如友盟统计SDK,官方给出的 ProGuard 配置都需要加上该配置,也就是说不进行代码优化、压缩,往往初次接触者不明所以的照搬了。但其实如果你的应用没有采用热更新方案之类的,在 ProGuard 里去掉这2个配置,你会发现这对减小 apk 的大小效果很显著。

以我们自己的一个应用为例,ProGuard 里加上这2个配置打出来的 apk 包大小约为 25.5M,去掉这2个配置之后打出的包大小约为 24.1M。简直不敢相信,就这么2个小小的配置,居然能让包大小缩减 1.4M 左右,效果非常明显。

但是,实操过程中,我们发现有些页面的图标丢失变成黑色了,这些因为 ProGuard 判定某些资源文件没有被使用,将它转换成了一个 1*1 的占位文件了。这需要我们手动在 res/raw/keep.xml 里配置,明确告诉 ProGuard 哪些资源文件是不需要混淆压缩的,以为自己的一个配置为例:

xmlns:tools="http://schemas.android.com/tools"

tools:shrinkMode="safe"

tools:keep="@mipmap/emoji_*,@mipmap/jietiao_ic_module_*"

>

7. 小结

采用 ProGuard 是减小 apk 大小非常有效的方法之一,但是使用过程中可能附带很多问题:有可能打包不成功、有可能图片资源问题丢失、有可能莫明其妙的闪退,这些都需要我们对 ProGuard 的配置有个基本的了解,遇到问题才能迎刃而解,用好了它相信会有很大的帮助。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值