Proguard特性
1、压缩:Java源代码通常被编译为字节码,虽然字节码比源代码更简洁,但它本身仍然会包含很多无用的代码。Proguard的压缩功能通过分析字节码,能够检测并移除没有使用的类,字段,方法和属性;
2、优化:优化Java字节码,同时移除没有使用到的指令;
3、混淆:使用无意义的简短字母组合对类名、字段名、方法名进行重命名;
4、预检验:对上述处理后的代码进行预检验;
混淆配置
buildTypes {
release {
minifyEnabled true //true表示使能Proguard
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
混淆文件的规则大致分为三类:
- 公共的混淆规则:每个APP都通用的,主要是对Proguard的基本配置,以及Android SDK中API设置的规则,例如Activity、Parcelable等;
- App特有的混淆规则:根据APP自身的特点进行设置,例如某些类会被反射调用,如果被混淆,那么反射就找不到类了;
- 第三方函数库或者SDK的混淆规则:如果APP引入了第三方开源函数库或者SDK,那么需要查看这些函数库或者SDK的使用说明,将需要去混淆的地方加上去;
混淆文件编写
#代码迭代优化的次数,取值范围0 - 7,默认5
-optimizationpasses 5
#混淆时不使用大小写混合的方式,这样混淆后都是小写字母的组合
-dontusemixedcaseclassnames
#混淆时不做欲校验,欲校验是Proguard四大功能之一,在Android中一般不需要欲校验,这样可以加快混淆的速度
-dontpreverify
#混淆时记录日志,同时会生成映射文件,Android Studio中,生成的默认映射文件是 'build/outputs/mapping/release/mapping.txt'
-verbose
#生成指定的映射文件的路径和名称
-printmapping build/outputs/mapping/release/mymapping.txt
#混淆时所采用的算法,参数是Google官方推荐的过滤器算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#如果项目中用到了注解,需要保留注解属性
-keepattributes *Annotation*
#不混淆泛型
-keepattributes Signature
#保留代码行号,这在混淆后代码运行中抛出异常信息时,有利于定位出问题的代码
-keepattributes SourceFile,LineNumberTable
#保持Android SDK相关API类不被混淆
-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 com.android.vending.licensing.ILicensingService
#保留R类
-keep class **.R$*{
*;
}
#保留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);
}
#保持Activity中参数是View类型的参数,保证在Layout XML文件配置的 onClick 属性的值能够正常调用到
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
#保持枚举类不被混淆
-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 *;
}
#保持Serializable序列化类相关方法和字段不被混淆
-keepclassmembers class * implements java.io.Serializable{
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
#保持自定义控件不被混淆
-keep public class * extends android.view.View{
public <init>(android.content.Context);
public <init>(android.content.Context,android.util.AttributeSet);
public <init>(android.content.COntext,android.util.AttributeSet,int);
public void set*(...);
*** get*();
}
#引入各个开源库需要增加的混淆