一.为什么要混淆压缩?
原因主要有三
- 增加反编译的成本
- 资源压缩 减少apk体积
- 代码压缩 规避64k方法限制
二.什么是混淆压缩?
混淆一般是指代码混淆,代码混淆指的是通过某种规则把方便阅读和理解的代码变得难以阅读和理解,这是增加反编译成本的原因。
Android中的混淆不止是代码混淆,还包括了资源压缩
1. 代码混淆
代码混淆主要包括以下四个方面
- 压缩:检测并删除无用的类,方法,变量和属性
- 优化:优化字节码并删除未使用的指令,优化后也会应用压缩
- 混淆:根据混淆字典,替换代码中的包名,类,方法和属性的名称,使得代码难以阅读和理解,它删除仅对调试有用的内部属性,例如源文件名,变量名和行号。
- 校验:对以上处理之后进行校验
2.资源压缩
开启资源压缩后,默认移除项目以及依赖仓库中所有未使用到的资源,可有效降低apk的体积。
资源压缩有以下⚠️三个注意点⚠️
- 自定义要保留的资源
如果希望保留或舍弃特定资源,请在项目中创建一个带有 <resources> 标记的 XML 文件,并在 tools:keep 属性中指定要保留的每个资源,在 tools:discard 属性中指定要舍弃的每个资源。这两个属性都接受逗号分隔的资源名称列表。可以将星号字符用作通配符。
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*" tools:discard="@layout/unused2" />
将此文件保存在项目资源中,例如,保存在 res/raw/keep.xml。编译系统不会将此文件打包到 APK 中。
- 启动严格检查模式,只保留真正使用到的资源
以下代码会使系统将所有带 img_ 前缀的资源标记为已使用。
val name = String.format("img_%1d", angle + 1) val res = resources.getIdentifier(name, "drawable", packageName)
请在 keep.xml 文件中将 shrinkMode 设为 strict
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools" tools:shrinkMode="strict" />
- 排查资源压缩问题
Gradle 还会在 <module-name>/build/outputs/mapping/release/(与 ProGuard 的输出文件所在的文件夹相同)中创建一个名为 resources.txt 的诊断文件。此文件包含一些详细信息,如哪些资源引用了其他资源以及使用或移除了哪些资源。
例如,要了解为什么 @drawable/ic_plus_anim_016 仍在您的 APK 中,请打开 resources.txt 文件并搜索相应的文件名。您可能会发现,有其他资源引用了它