ProGuard的使用是为了:
1、创建紧凑的代码文档是为了更快的网络传输,快速安装和更小的内存占用。
2、创建的程序和程序库很难使用反向工程(防止被破解)。
3、所以它能删除来自源文件中的没有调用的代码(删除无用的文件)。
4、充分利用java6的快速加载的优点来提前检测和返回java6中存在的类文件。
混淆要经历四步:
1、shrink 瘦身-去除无用代码,
2、optimize 优化-优化方法的字节码 (代码优化控制:控制混淆是否开启优化代码,以及代码优化级别),
3、obfuscate 混淆-用无意义段短名称替代 ,
4、preverify 预验证-添加预验证信息
混淆规则基本语法:混淆文件采用白名单法,不在白名单里面的都要混淆。
混淆规则的基本符号:
1)# 代表行注释符,表示注释某一行
2)- 表示一条规则的开始
3)keep 保留,例如keepattributes:表示保留不要被混淆
4)dont 不要,例如dontwarn:表示不要提示警告
5)ignore 忽略,例如ignorewarning:表示忽略警告
proguard 可能会产生的问题:
1,混淆错误,用到第三方库的时候,必须告诉 proguard不要检查,否则proguard会报错。
2,运行错误,当code 不能混淆的时候,我们必须要正确配置,否则程序会运行出错,这种情况问题最多。
3,调试苦难,出错了,错误堆栈是混淆后的代码 ,自己也看不懂。
例子:
-dontwarn org.apache.log4j.*
-keep class org.apache.log4j.** { *;}
将-dontwarn和-keep 结合使用,意思是保持包里面的所有类和所有方法而不混淆,
接着还叫ProGuard不要警告找不到这个包里面的类的相关引用。
混淆的模板规则:
# 混淆时的代码优化控制
# 不优化 (optimize:优化)
-dontoptimize
# 代码循环优化次数,0-7,默认为5
-optimizationpasses 7
# 混淆时所采用的优化规则(优化算法)
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
# 优化时允许访问并修改有修饰符的类和类的成员,这可以提高优化步骤的结果
-allowaccessmodification
# 压缩设置
# 不进行压缩(shrink:压缩) 默认是要压缩的,除了-keep列出的class和这些类文件直接或间接引用的文件间外其它类文件都会被移除,
# 压缩步骤在优化之后执行,因为优化可能会移除更多的类文件和类成员。
-dontshrink
# 混淆时不使用大小写混合(这样就不会产生形形色色的类名)
-dontusemixedcaseclassnames
# 指定不去忽略非公共的库类以及类的成员(不能忽略私有的类以及类的成员)(不混淆第三方的jar包)
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
# 不预校验
-dontpreverify
# 如果找不到这个包里面的类的相关引用,不要提示警告(不提示类的引用的警告)
-dontwarn
# 混淆时是否记录日志
-verbose
# 混淆前后的映射
# mapping.txt列出了原始的类,方法和字段名与混淆后代码间的映射。这个文件很重要,当你从release版本中收到一个bug报告时,可以用它来翻译被混淆的代码。
# mapping目录在\app\build\outputs\mapping\release (其实就是翻译规则)
-printmapping map.txt
# 保持继承自这些类的文件不被混淆(这些类都是系统类,混淆文件一般都有的)
-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.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.os.IInterface
-keep public class * extends android.os.ResultReceiver
-keep public class * extends android.appwidget.AppWidgetProvider
-keep public class * extends android.webkit.*{*;}
-keep public class * extends android.widget.*{*;}
-keep public class * extends android.app.*{*;}
-keep public class com.android.vending.licensing.ILicensingService
# 保持native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
# 保持自定义控件类不被混淆(这是模板代码)
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# 保持枚举enum类不被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保持实现Parcelable接口的类不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# 保持实体类不被混淆
-keep class 包名.domain.**{*;}
# 翼支付
# 保持bestpay这个包下所有的类以及其中的方法不被混淆
-keep class com.bestpay.** {*;}
# 保持passguard这个包下所有的类以及其中的方法不被混淆(多级包)
-keep class cn.passguard.*{*;}
# 如果使用了小米推送,要保持“MiMsgReceiver”类中的方法不被混淆
-keep class cn.TuHu.Receiver.MiMsgReceiver {*;}
# 魔窗
-keep class com.zxinsight.** {*;}
-dontwarn com.zxinsight.**
# afinal的混淆规则:
-keep class net.tsz.afinal.** {*;}
-keep public class * extends net.tsz.afinal.**
-keep public interface net.tsz.afinal.** {*;}
# 支付宝支付的混淆
-keep class com.alipay.android.app.IAliPay{*;}
-keep class com.alipay.android.app.IAlixPay{*;}