混淆(proguard)配置

配置说明

保留选项

-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 <methods>;
}

#不混淆资源类
-keepclassmembers class **.R$* {
    public static <fields>;
}

#保留使用的四大组件,自定义的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 <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(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中的内部类):
-keep class com.dev.example.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{
     <init>;     //匹配所有构造器
     <fields>;   //匹配所有域
     <methods>;  //匹配所有方法
}
还可以保留的更具体一点,如下所示

-keepclassmembers com.dev.example.TaskRepository{
     // 保留该类的修饰符是public且有一个参数(类型是String)的构造方法
     public <init>(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.* <fields>;
}

-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

#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 <methods>;
}

# 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调用也需要保证写的接口方法不混淆

猜你喜欢

转载自blog.csdn.net/AHAI1078766113/article/details/81540720
今日推荐