优化。分析和优化方法的二进制代码;根据proguard-android-optimize.txt
中的描述,优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行。
混淆。把类名、属性名、方法名替换为简短且无意义的名称;
预校验。添加预校验信息。这个预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度。
这四个流程默认开启。
在Android
项目中我们可以选择将“优化”和“预校验”关闭,对应命令是-dontoptimize、-dontpreverify
(当然,默认的 proguard-android.txt
文件已包含这两条混淆命令,不需要开发者额外配置)。
资源压缩
====
资源压缩将移除项目及依赖的库中未被使用的资源,这在减少apk
包体积上会有不错的效果,一般建议开启。具体做法是在 build.grade
文件中,将shrinkResources
属性设置为true
。需要注意的是,只有在用minifyEnabled true
开启了代码压缩后,资源压缩才会生效。
资源压缩包含了“合并资源”和“移除资源”两个流程。
“合并资源”流程中,名称相同的资源被视为重复资源会被合并。需要注意的是,这一流程不受shrinkResources
属性控制,也无法被禁止,gradle
必然会做这项工作,因为假如不同项目中存在相同名称的资源将导致错误。gradle
在四处地方寻找重复资源:
src/main/res/
路径
不同的构建类型(debug
、release
等等)
不同的构建渠道
项目依赖的第三方库
合并资源时按照如下优先级顺序
依赖 -> main -> 渠道 -> 构建类型
假如重复资源同时存在于main文件夹和不同渠道中,gradle 会选择保留渠道中的资源。
同时,如果重复资源在同一层次出现,比如src/main/res/ 和 src/main/res2/
,则 gradle
无法完成资源合并,这时会报资源合并错误。
“移除资源”流程则见名知意,需要注意的是,类似代码,混淆资源移除也可以定义哪些资源需要被保留,这点在下文给出。
自定义混淆规则
=======
在上文“混淆配置”中有这样一行代码
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ‘proguard-rules.pro’
这行代码定义了混淆规则由两部分构成:位于 SDK 的 tools/proguard/ 文件夹中的 proguard-android.txt 的内容以及默认放置于模块根目录的 proguard-rules.pro 的内容。前者是 SDK 提供的默认混淆文件,后者是开发者自定义混淆规则的地方。
常见的混淆指令
=======
-
optimizationpasses
-
dontoptimize
-
dontusemixedcaseclassnames
-
dontskipnonpubliclibraryclasses
-
dontpreverify
-
dontwarn
-
verbose
-
optimizations
-
keep
-
keepnames
-
keepclassmembers
-
keepclassmembernames
-
keepclasseswithmembers
-
keepclasseswithmembernames
更多详细的请到官网
需要特别介绍的是与保持相关元素不参与混淆的规则相关的几种命令:
| 命令 | 作用 |
| — | — |
| -keep | 防止类和成员被移除或者被重命名 |
| -keepnames | 防止类和成员被重命名 |
| -keepclassmembers | 防止成员被移除或者被重命名 |
| -keepnames | 防止成员被重命名 |
| -keepclasseswithmembers | 防止拥有该成员的类和成员被移除或者被重命名 |
| -keepclasseswithmembernames | 防止拥有该成员的类和成员被重命名 |
保持元素不参与混淆的规则
[保持命令] [类] {
[成员]
}
“类”代表类相关的限定条件,它将最终定位到某些符合该限定条件的类。它的内容可以使用:
-
具体的类
-
访问修饰符(public、protected、private)
-
通配符*,匹配任意长度字符,但不含包名分隔符(.)
-
通配符**,匹配任意长度字符,并且包含包名分隔符(.)
-
extends,即可以指定类的基类
-
implement