Android Studio混淆

使用Android Gradle插件3.4.0或更高版本构建项目时,不再使用ProGuard执行编译时代码优化,而是与R8编译器协同工作

开启混淆

  在gradle文件中启用混淆,在混淆配置文件中,getDefaultProguardFile('proguard-android-optimize.txt')代表sdk目录tools\proguard路径下的默认混淆配置文件,proguard-rules.txt代表项目根目录下的开发者自定义混淆配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
android {
buildTypes {
release {
// 启用代码压缩、混淆和优化
minifyEnabled true

// 启用资源压缩
shrinkResources true

// 添加混淆配置文件
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.txt'
}
}
}

混淆命令

命令作用
-keep防止类和成员被移除和被重命名
-keepnames防止类和成员被重命名
-keepclassmembers防止成员被移除和被重命名
-keepclassmembernames防止成员被重命名
-keepclasseswithmembers防止拥有该成员的类和成员被移除或重命名
-keepclasseswithmembernames防止拥有该成员的类和成员被重命名

-keep

类和类成员均不压缩和混淆。类和类成员在未使用的情况下不被删除,并保留原始名称

1
2
3
-keep class com.test.packagename.Bean {
*;
}

-keepnames

允许类和类成员压缩,不允许混淆。类和成员未使用时将会被删除,使用时保留原始名称

1
2
3
-keepnames class com.test.packagename.Bean {
*;
}

-keepclassmembers

允许类压缩和混淆,不允许类成员压缩和混淆。类未使用时将被删除,类使用时不保留原始名称,但类成员不会被删除且保留原始名称

1
2
3
-keepclassmembers class com.test.packagename.Bean {
*;
}

-keepclassmembernames

允许类压缩和混淆,类成员仅允许压缩不允许混淆。类未使用时将会被删除,类使用时不保留原始名称,类成员未使用是将被删除,类成员使用时保留原始名称

1
2
3
-keepclassmembernames class com.test.packagename.Bean {
*;
}

-keepclasseswithmembers

指定的类和类成员不压缩和混淆。被指定的类和类成员在未使用的情况下不被删除,并保留原始名称

1
2
3
4
# 指定类及所有类成员不被压缩和混淆
-keepclasseswithmembers class com.test.packagename.Bean {
*;
}

-keepclasseswithmembernames

指定类和类成员仅允许压缩,不允许混淆。被指定的类和成员在未使用时将会被删除,使用时保留原始名称

1
2
3
4
# 指定类及所有类成员允许压缩不允许混淆
-keepclasseswithmembernames class com.test.packagename.Bean {
*;
}

混淆规则

1
2
3
[命令] [修饰符] [类|接口|枚举] [类名|接口名|枚举名] {
[成员]
}

命令规则

仅支持填入保持命令

  • -keep
  • -keepnames
  • -keepclassmembers
  • -keepclassmembernames
  • -keepclasseswithmembers
  • -keepclasseswithmembernames

类规则

保持类(接口、枚举也属于类的一种)com.test.packagename.Bean和类成员不压缩、不混淆

1
2
3
4
5
6
7
8
-keep class com.test.packagename.Bean {
[成员]
}

保持包`com.test.packagename`下的所有类、接口、枚举及其成员不压缩、不混淆
-keep class com.test.packagename.* {
[成员]
}

接口

保持接口com.test.packagename.CallBack和成员不压缩、不混淆

1
2
3
-keep interface com.test.packagename.CallBack {
[成员]
}

枚举

保持枚举com.test.packagename.Param和成员不压缩、不混淆

1
2
3
-keep enum com.test.packagename.Param {
[成员]
}

支持逻辑非!

不保持com.test.packagename包下的接口,保持其余所有类、接口、枚举及其成员不压缩、不混淆

1
2
3
-keep !interface com.test.packagename.* {
[成员]
}

修饰符规则

修饰符可以留空,留空则代表同时选中public!public

public

仅保持com.test.packagename下的public类和类成员不压缩、不混淆

1
2
3
-keep public class com.test.packagename.* {
[成员]
}

!public

仅保持com.test.packagename包下的非public类和类成员不压缩、不混淆

1
2
3
-keep !public class com.test.packagename.* {
[成员]
}

类名规则

直接写入

保持类com.test.packagename.Bean和类成员不压缩、不混淆

1
2
3
-keep class com.test.packagename.Bean{
*;
}

通配符

保持com.test.packagename包下所有类和类成员不压缩、不混淆

1
2
3
-keep class com.test.packagename.* {
*;
}

保持com.test.packagename包及其子包下所有类和类成员不压缩、不混淆

1
2
3
-keep class com.test.packagename.** {
*;
}

继承类、实现接口

保持所有继承了android.app.Activity的类和类成员不压缩、不混淆

1
2
3
-keep class com.test.packagename.** extends android.app.Activity {
*;
}

保持所有实现了java.io.Serializable的类和类成员不压缩、不混淆

1
2
3
-keep class com.test.packagename.** implements java.io.Serializable {
*;
}

内部类

保持类com.test.packagename.Bean中的所有子类和子类成员不压缩、不混淆

1
2
3
-keep class com.test.packagename.Bean$* {
*;
}

成员规则

构造器规则

空参构造器

保持com.test.packagename包下所有类和类的空参构造器不压缩、不混淆

1
2
3
-keep class com.test.packagename.** {
<init>();
}

任意构造器

保持com.test.packagename包下所有类和类中构造器不压缩、不混淆

1
2
3
-keep class com.test.packagename.** {
<init>(*);
}

指定参数构造器

保持com.test.packagename包下所有类和类中接收String参数的构造器不压缩、不混淆

1
2
3
-keep class com.test.packagename.** {
<init>(java.lang.String);
}

任意参数构造器

保持com.test.packagename包下所有类和类中接收任意参数的构造器不压缩、不混淆

1
2
3
-keep class com.test.packagename.** {
<init>(...);
}

方法规则

所有方法

保持com.test.packagename包下所有类和成员方法不压缩、不混淆

1
2
3
4
5
6
7
8
-keep class com.test.packagename.** {
<methods>;
}

// # 另一种写法,二者等效
// -keep class com.test.packagename.** {
// *(*);
// }

指定方法

保持com.test.packagename包下所有类和类中main方法不压缩、不混淆

1
2
3
-keep class com.test.packagename.** {
main();
}

还有访问修饰符、通配符、返回值、接收参数,他妈的不写了

常用规则

关闭压缩

1
-dontshrink

关闭代码优化,默认Proguard规则文件已包含

1
-dontoptimize

关闭混淆

1
-dontobfuscate

指定代码优化级别,值在0-7之间,默认为5

1
-optimizationpasses 5

混淆时不使用大小写混合类名,默认Proguard规则文件已包含

1
-dontusemixedcaseclassnames

不忽略库中的非public的类,默认Proguard规则文件已包含

1
-dontskipnonpubliclibraryclasses

不忽略库中的非public的类成员

1
-dontskipnonpubliclibraryclassmembers

输出详细信息,默认Proguard规则文件已包含

1
-verbose

不做预校验,预校验是作用在Java平台上的,Android平台上不需要这项功能,去掉之后还可以加快混淆速度,默认Proguard规则文件已包含

1
-dontpreverify

保持指定包下的类名,不包括子包下的类名

1
-keep class com.test.packagename*

保持指定包下的类名,包括子包下的类名

1
-keep class com.test.packagename**

保持指定包下的类名及其所有成员、方法和字段的命名

1
-keep class com.test.packagename.* {*;}

保持所有继承于指定类的类,如下保持所有继承Activity的类

1
-keep public class * extends android.app.Activity

简书文章:https://www.jianshu.com/p/c19444e5d3aa
简书文章:https://www.jianshu.com/p/fdadca8e2094
Android 开发者文档:http://developer.android.google.cn/guide/developing/tools/proguard.html
ProGuard 官方文档:https://www.guardsquare.com/manual/home