Android提供的proguard.cfg文件可以用来配置代码混淆,不过默认情况下是关闭的,下面是android studio中开启混淆的方法:
android {
buildTypes {
debug{
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg'
}
}
}
其中proguard-android.txt可以不用管,是在SDK目录\tools\proguard
的,后面的proguard.cfg换成你具体的文件名,这样就能开启混淆了
1. 不混淆类名:
-keep class com.example.test.EncryptStatus
注意:keep class包含了keep interface效果,keep interface只对接口有效
2. 不混淆一个包下面所有类的类名:
-keep class com.example.test.*
3. 不混淆一个包以及所有子包下所有类的类名:
-keep class com.example.test.**
4. 不混淆一个类的类名以及该类下所有属性和方法:
-keep class com.example.test.EncryptStatus{*;}
5. 不混淆所有继承一个类的子类类名:
-keep class * extends com.example.test.EncryptStatus
6. 不混淆所有实现一个接口的子类类名:
-keep class * implements com.example.test.EncryptStatus
7. 保留所有类中定义的enum结构体以及里面的属性和方法:
-keepattributes InnerClasses
-keep enum *{*;}
注意:必须加上InnerClasses属性,否则无效,刚开始在网上找好多都没说明这点,走了不少弯路
8. 保留一个类中的所有内嵌类类名:
-keepattributes InnerClasses
-keep class com.example.test.EncryptStatus$*
注意:要想保留内嵌类,必须先保留InnerClasses属性,否则无效
9. 保留一个类中的静态属性和静态方法:
-keepclassmembers class com.example.test.EncryptStatus {
public static <fields>;
public static <methods>;
}
注意:
如果一个类的构造函数没有被调用过混淆的优化这一步就会把这个构造函数去掉,因此可以用keepclassmembers保留,下面是keepclassmembers与keepclassmembernames区别:
keepclassmembers 只保留类中的成员,防止它们被混淆或移除
keepclassmembernames 只保留类中的成员,防止它们被混淆,但当成员没有被引用时会被移除
i. <init>; //匹配所有构造器
ii. <fields>; //匹配所有域
iii. <methods>; //匹配所有方法方法
iv. 上面三个前面只能加修饰符,类似public static final,native 等,除此之外如果加类型,如int,虽然编译不会报错,但是测过是无效的
10. 保留具体变量名或方法:
-keepclasseswithmembers class * {
private static final String TAG;
private *** te*(...);
public static **[] values();
}
注意:
i. 上面的*不同的位置匹配规则不同,te*中的*代表一个匹配多个,它前面的***代表匹配所有类型,包括初始类型(int, boolean, long, float,double等)和非初始类型,数组和非数组,一个*不能用来匹配前面返回类型,可以用**或***匹配返回类型,**或***可以不止代表一个单词。
ii. 注意的是?, *, **不能够匹配初始类型和数组,例如** get*()可以匹配到java.lang.Object getObject(),但是不能匹配float getFloat()或者java.lang.Object[] getObjects(),如果要用**匹配数组可以类似**[]方式就行。
iii. “…”匹配所有参数列表
iv. {}里面列到的属性和方法必须都具备才会执行保留类名和成员,一个不满足都不会执行
v. 如果只想保留成员,可以用-keepclassmembers替代
11. 去除某个包下所有警告信息:
-dontwarn com.example.**
12.常用类混淆
-keep class com.test.plugins.**{*;}会保留plugins目录下所有类以及子类
-keep class com.test.plugins.Test{*;}只会保留Test类,里面的内部类不会保留
-keep class com.test.plugins.Test$*{*;} 会保留Test所有内部类,但是不会保留Test类
-keep class com.test.plugins.Test*{*;} 会保留Test类以及它的所有内部类