配置说明
保留选项
-keep {Modifier} {class_specification} 保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
压缩
-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}
优化
-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员
混淆
-dontobfuscate 不混淆输入的类文件
-printmapping {filename}
-applymapping {filename} 重用映射增加混淆
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
-keepattributes {attribute_name,…} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string} 设置源文件中给定的字符串常量
屏蔽警告信息
-dontwarn 不对指定的类、包中的不完整的引用发出警告
通用配置
代码混淆压缩比,在0~7之间,默认为5,一般不做修改
-optimizationpasses 5
把混淆类中的方法名也混淆了
-useuniqueclassmembernames
优化时允许访问并修改有修饰符的类和类的成员
-allowaccessmodification
避免混淆内部类、泛型、匿名类
-keepattributes InnerClasses,Signature,EnclosingMethod
抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
重命名抛出异常时的文件名称为”SourceFile”
-renamesourcefileattribute SourceFile
保持 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;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
保留JNI类
-keepclasseswithmembernames class * {
native ;
}
不混淆资源类
-keepclassmembers class *.R$ {
public static ;
}
保留使用的四大组件,自定义的Application等等这些类不被混淆
因为这些子类都有可能被外部调用
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
保留support下的所有类及其内部类
-keep class android.support.* {;}
保留继承的support类
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
保留们自定义控件(继承自View)不被混淆
-keep public class * extends android.view.View{
* get*();
void set*(*);
public (android.content.Context);
public (android.content.Context, android.util.AttributeSet);
public (android.content.Context, android.util.AttributeSet, int);
}
Fragment不需要在AndroidManifest.xml中注册,需要额外保护下
-keep public class * extends android.app.Fragment
保持测试相关的代码
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**
针对App的配置
实体类需要保留,实体类的get和set方法(尤其是反射会用到的,不保留可能有些json解析不匹配),boolean类型的get方法是isXXX,不要忘记保留。
-keep public class com.dev.example.entity.** {
public void set*(*);
public * get*();
public * is*();
}
注意:保留实体类时也可以按照类名所包含某些字母来筛选,如(名字中带有Model的):
-keep public class .Model. {
public void set*(*);
public * get*();
public * is*();
}
保留写在某个类里面的所有内部类,如以下类A中所有的内部类将会被保留
-keep class com.dev.example.A$* { *; }
其中{*;}匹配该类里面的所有部分
如果要保留内部类中的内部类则可以连续拼上
符号,如(保留类A中内部类B中的内部类):−keepclasscom.dev.example.A
符
号
,
如
(
保
留
类
A
中
内
部
类
B
中
的
内
部
类
)
:
−
k
e
e
p
c
l
a
s
s
c
o
m
.
d
e
v
.
e
x
a
m
p
l
e
.
A
B$* { *; }
对webView进行处理
-keepclassmembers class fqcn.of.javascript.interface.for.webview {
public *;
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.webView, java.lang.String);
}
如果我们的app中涉及到和h5交互,需要保留js调用的原生方法
Keep JavascriptInterface
-keepclassmembers class ** {
@android.webkit.JavascriptInterface public *;
}
对含有反射类的处理,有时候项目中有些类不是实体类,但仍然用到反射功能,如Class.forName(“xxx”),这是我们需要保留的。比如这些类在com.dev.example包下,可以通过下面的配置进行保留。
-keep class com.dev.example.* { *; }
另外上面只是保留了该包下的类,如果该包下还有子包,则子包的类仍然会被混淆,
如果想保留该包下子包的类,我们可以如下配置(**能匹配本包和所含子包,其中子包也可以含有子包)
-keep class com.dev.example.*{ ; }
常见的自定义的配置
1.保留某个特定的类
保留Test类
-keep public class com.dev.example.Test { *; }
2.保留某个类的子类
保留继承了AbstractClass的子类
-keep class * extends com.dev.example.AbstractClass{*;}
3.保留接口的实现类
保留实现了Callable接口的类
-keep class * implements Callable{*;}
4.保留类的特定部分,如:保留TaskRepository类的所有构造方法,变量和普通方法。
-keep class com.dev.example.TaskRepository{
; //匹配所有构造器
; //匹配所有域
; //匹配所有方法
}
还可以保留的更具体一点,如下所示
-keepclassmembers com.dev.example.TaskRepository{
// 保留该类的修饰符是public且有一个参数(类型是String)的构造方法
public (java.lang.String);
// 保留该类的所有修饰符是public且返回类型void的方法
public void (*);
// 保留该类的具体某一个方法
public String getUserName();
}
常见的第三方库
okhttp
-dontwarn com.squareup.okhttp.**
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.* { ;}
-dontwarn okio.**
retroift
-dontwarn retrofit2.**
-keep class retrofit2.* { ; }
-keepattributes Signature
-keepattributes Exceptions
fresco SDK
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
@com.facebook.common.internal.DoNotStrip *;
}
rx
-dontwarn rx.**
-keep class rx.* { ;}
keep GSON stuff
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.* { ; }
ButterKnife
-keep class butterknife.* { ; }
-dontwarn butterknife.internal.**
-keep class *$$ViewBinder { ; }
-keepclasseswithmembernames class * {
@butterknife.* ;
}
-keepclasseswithmembernames class * {
@butterknife.* ;
}
enventbus
-keep class org.greenrobot.eventbus.* { ;}
-dontwarn org.greenrobot.eventbus.**
-keepclassmembers class ** {
public void onEvent*(**);
}
Bugly
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.*{;}
aliyun push
-keepclasseswithmembernames class ** {
native ;
}
QQ share SDK
-dontwarn com.tencent.**
-keepnames class com.tencent.* {;}
sina share SDK
-dontwarn com.sina.**
-keepnames class com.sina.* {;}
umeng SDK
-keep public class * extends com.umeng.**
-dontwarn com.umeng.**
-keep class com.umeng.* { ; }
不混淆规则
1、反射用到的类不能混淆,JNI方法不混淆
2、AndroidMainfest中的类不混淆
3、四大组件和Application的子类和Framework 层下所有的类默认不会进行混淆
4、Parcelable的子类和Creator 静态成员变量不混淆,否则会产生 android.os.BadParcelableException 异常
5、使用GSON、fastjson等框架时,所写的JSON 对象类不混淆,否则无法将JSON解析成对应的对象
6、使用第三方开源库或者引用其他第三方的SDK包时,需要在混淆文件中加入对应的混淆规则
7、有用到WebView的JS调用也需要保证写的接口方法不混淆