Proguard特性
1部凑、壓縮:Java源代碼通常被編譯為字節(jié)碼分歇,雖然字節(jié)碼比源代碼更簡潔善炫,但它本身仍然會(huì)包含很多無用的代碼例驹。Proguard的壓縮功能通過分析字節(jié)碼捐韩,能夠檢測并移除沒有使用的類,字段鹃锈,方法和屬性荤胁;
2、優(yōu)化:優(yōu)化Java字節(jié)碼屎债,同時(shí)移除沒有使用到的指令仅政;
3垢油、混淆:使用無意義的簡短字母組合對類名、字段名已旧、方法名進(jìn)行重命名;
4召娜、預(yù)檢驗(yàn):對上述處理后的代碼進(jìn)行預(yù)檢驗(yàn)运褪;
混淆配置
buildTypes {
release {
minifyEnabled true //true表示使能Proguard
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
混淆文件的規(guī)則大致分為三類:
- 公共的混淆規(guī)則:每個(gè)APP都通用的,主要是對Proguard的基本配置玖瘸,以及Android SDK中API設(shè)置的規(guī)則秸讹,例如Activity、Parcelable等雅倒;
- App特有的混淆規(guī)則:根據(jù)APP自身的特點(diǎn)進(jìn)行設(shè)置璃诀,例如某些類會(huì)被反射調(diào)用,如果被混淆蔑匣,那么反射就找不到類了劣欢;
- 第三方函數(shù)庫或者SDK的混淆規(guī)則:如果APP引入了第三方開源函數(shù)庫或者SDK,那么需要查看這些函數(shù)庫或者SDK的使用說明裁良,將需要去混淆的地方加上去凿将;
混淆文件編寫
#代碼迭代優(yōu)化的次數(shù),取值范圍0 - 7价脾,默認(rèn)5
-optimizationpasses 5
#混淆時(shí)不使用大小寫混合的方式牧抵,這樣混淆后都是小寫字母的組合
-dontusemixedcaseclassnames
#混淆時(shí)不做欲校驗(yàn),欲校驗(yàn)是Proguard四大功能之一侨把,在Android中一般不需要欲校驗(yàn)犀变,這樣可以加快混淆的速度
-dontpreverify
#混淆時(shí)記錄日志,同時(shí)會(huì)生成映射文件秋柄,Android Studio中获枝,生成的默認(rèn)映射文件是 'build/outputs/mapping/release/mapping.txt'
-verbose
#生成指定的映射文件的路徑和名稱
-printmapping build/outputs/mapping/release/mymapping.txt
#混淆時(shí)所采用的算法,參數(shù)是Google官方推薦的過濾器算法
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#如果項(xiàng)目中用到了注解骇笔,需要保留注解屬性
-keepattributes *Annotation*
#不混淆泛型
-keepattributes Signature
#保留代碼行號(hào)映琳,這在混淆后代碼運(yùn)行中拋出異常信息時(shí),有利于定位出問題的代碼
-keepattributes SourceFile,LineNumberTable
#保持Android SDK相關(guān)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序列化類相關(guān)方法和字段不被混淆
-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*();
}
#引入各個(gè)開源庫需要增加的混淆