简介

ProGuard能够通过移除无用代码、使用简短无意义名称重命名类字段方法等方式,实现压缩、优化、混淆代码的目的。

工作原理

详见Proguard手册

  1. 压缩(Shrink):检测并删除未使用的类、字段、方法、属性。
  2. 优化(Optimize):优化字节码、移除无用指令。
  3. 混淆(Obfuscate):使用abc等简短无意义的名称,重命名类、字段、方法。
  4. 预检(Preveirfy):预检处理后的代码。

图片

教程

ProGuard

ProGuard现已经集成到Android构建系统中,在Android Studio中需要将其添加到build.gradle的构建类型中,不过在创建项目时这个操作已经自动完成。

build.gradle(Module)
1
2
3
4
5
6
7
8
9
buildTypes {
release {
minifyEnabled true //启用混淆
zipAlignEnabled true //优化zipalign
shrinkResources true //压缩资源
buildConfigField "boolean", "LOG_DEBUG", "false" //隐藏日志
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' //前一部分为系统默认的混淆文件/tools/proguard/proguard-android.txt, 后一部分为自定义的混淆文件app/proguard-rules.pro
}
}

proguard-rules.pro

如下为proguard-rules.pro配置的通用部分,如需使用直接复制,然后根据项目与第三方库的情况进行修改即可。

proguard-rules.pro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#############################################
#
# 第三方库
#
#############################################


#############################################
#
# 基本指令
#
#############################################

# 混淆压缩比
-optimizationpasses 5

# 混合时不使用大小写混合
-dontusemixedcaseclassnames

# 混淆后产生映射文件
-verbose

# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable

# 不进行预校验
-dontpreverify

# 不忽略非公共库的类
-dontskipnonpubliclibraryclasses

# 不忽略非公共库的类成员
-dontskipnonpubliclibraryclassmembers

# 保留Annotation
-keepattributes *Annotation*,InnerClasses

# 保留泛型
-keepattributes Signature

# 指定混淆算法
-optimizations !code/simplification/artithmetic,!field/*,!class/merging/*

#############################################
#
# 公共部分
#
#############################################

# 保留四大组件
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class * extends android.database.sqlite.SQLiteOpenHelper{*;}

# 保留Appcompat下的所有类及其内部类
-keep class androidx.appcompat.* {*;}

# 保留R下的资源
-keep class **.R$* {*;}

# 保留本地Native方法
-keepclasseswithmembernames class * {
native <methods>;
}

# 保留在Activity中的方法参数是View的方法
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}

# 保留枚举类
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}

# 保留继承自View的自定义控件
-keep public class * extends android.view.View{
void set*(***);
*** get*();
}

# 保留Parcelable序列化类
-keep class * implements android.os.Parcelable{
public static final android.os.Parcelable$Creator *;
}

# 保留Serializable序列化的类
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}

# 保留带有回调函数的onEvent或onListener
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
}

# 保留带有注释的Javascript接口方法
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}

# 保留@Keep支持注释
-keep class androidx.annotation.Keep
-keep @androidx.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <init>(...);
}

参考资料