混淆使用
android {
...
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
混淆後默認會在工程目錄app/build/outputs/mapping/release下生成一個mapping.txt文件
ProGuard作用
壓縮(Shrinking)
默認開啓,用以減小應用體積,移除未被使用的類和成員,並且會在優化動作執行之後再次執行(因爲優化後可能會再次暴露一些未被使用的類和成員)-dontshrink 關閉壓縮
優化(Optimization)
默認開啓,在字節碼級別執行優化,讓應用運行的更快-dontoptimize 關閉優化
-optimizationpasses n 表示proguard對代碼進行迭代優化的次數,Android一般爲5混淆(Obfuscation)
默認開啓,增大反編譯難度,類和類成員會被隨機命名,除非用keep保護。-dontobfuscate 關閉混淆
混淆規則
只是保持該包下的類名,而子包下的類名還是會被混淆
-keep class cn.proguard.test.*
把本包和所含子包下的類名都保持
-keep class cn.proguard.test.**
既想保持類名,又想保持裏面的內容不被混淆
-keep class cn.proguard.test.* {*;}
保留一個類中的內部類不被混淆則需要用$符號
-keepclassmembers class cn.proguard.test$proguard {
public *;
}
不希望保持全部內容不被混淆,而只是希望保護類下的特定內容
<init>; //匹配所有構造器
<fields>; //匹配所有域
<methods>; //匹配所有方法方法
還可以在<fields>或<methods>前面加上private 、public、native等來進一步指定不被混淆的內容
-keep class cn.proguard.test.One {
public <methods>;
}
表示One類下的所有public方法都不會被混淆,當然你還可以加入參數,比如以下表示用JSONObject作爲入參的構造函數不會被混淆
-keep class cn.proguard.test.One {
public <init>(org.json.JSONObject);
}
防止被移除或者被重命名
-keep類和類成員
-keepclassmembers僅類成員
-keepclasseswithmembers如果擁有某成員,保留類和類成員
常用混淆
-keepclasseswithmembernames class * { # 保持native方法不被混淆
native <methods>;
}
-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆
public static final Android.os.Parcelable$Creator *;
}
-keepclassmembers enum * { #使用enum類型時,因爲enum類的特殊性,以下兩個方法會被反射調用
public static **[] values();
public static ** valueOf(java.lang.String);
}
注意
- 反射用到的類不混淆(否則反射可能出現問題);
- 所寫的JSON對象類不混淆,否則無法將JSON解析成對應的對象;
- WebView的JS調用需要保證寫的接口方法不混淆,原因和第一條一樣