Proguard特性
1、壓縮:Java源代碼通常被編譯為字節(jié)碼,雖然字節(jié)碼比源代碼更簡潔,但它本身仍然會包含很多無用的代碼。Proguard的壓縮功能通過分析字節(jié)碼,能夠檢測并移除沒有使用的類,字段,方法和屬性;
2、優(yōu)化:優(yōu)化Java字節(jié)碼,同時移除沒有使用到的指令;
3、混淆:使用無意義的簡短字母組合對類名、字段名、方法名進行重命名;
4、預檢驗:對上述處理后的代碼進行預檢驗;
混淆配置
buildTypes {
release {
minifyEnabled true //true表示使能Proguard
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
混淆文件的規(guī)則大致分為三類:
- 公共的混淆規(guī)則:每個APP都通用的,主要是對Proguard的基本配置,以及Android SDK中API設置的規(guī)則,例如Activity、Parcelable等;
- App特有的混淆規(guī)則:根據(jù)APP自身的特點進行設置,例如某些類會被反射調(diào)用,如果被混淆,那么反射就找不到類了;
- 第三方函數(shù)庫或者SDK的混淆規(guī)則:如果APP引入了第三方開源函數(shù)庫或者SDK,那么需要查看這些函數(shù)庫或者SDK的使用說明,將需要去混淆的地方加上去;
混淆文件編寫
#代碼迭代優(yōu)化的次數(shù),取值范圍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
#混淆時所采用的算法,參數(shù)是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中參數(shù)是View類型的參數(shù),保證在Layout XML文件配置的 onClick 屬性的值能夠正常調(diào)用到
-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*();
}
#引入各個開源庫需要增加的混淆