proguard-android.txt與proguard-android-optimize.txt
當我們打Release的時候,Google會默認對我們的release包進行優化,這個優化是通過在modeule中build.gradle中的minifyEnabled來開啓的。
android {
buildTypes {
release {
minifyEnabled true //開啓代碼混淆
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
但是如果我們將minifyEnabled置爲false的話,那麼在我們打release包的時候將不會對代碼進行混淆,實際上這也是一種比較危險的做法,我們的代碼經過反編譯之後就會被別人清晰地看到。
我們還可以看到下面的這段代碼
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
其中的proguard-android.txt是默認的配置文件,Google已經爲我們做好的最基本的配置,同時,如果我們想要進一步的對混淆配置進行優化的話,可以使用另一個配置,proguard-android-optimize.txt。
proguard-android-optimize.txt可以說是proguard-android.txt中的擴展版,它不僅僅包含了proguard-android.txt中已有的部分,也多了其他的優化部分,它會對字節碼也進行分析優化,進一步縮小APK的體積,提高應用運行速度。
在能編過的情況下,,這兩個文件已經能夠滿足我們對混淆的要求,但是如果我們引入了其他的一些庫,需要對混淆配置進行改動的話,則需要自定義proguard-rules.pro這個文件,實際上,我們也可以自已創建文件,並替換掉proguard-rules.pro,只要和proguard-rules.pro文件在一個目錄下就行。
proguard-rules.pro與Proguard規則
引入proguard-rules.pro的原因主要是,google爲我們配置了默認的混淆規則,但是在項目龐大,系統默認的規則還不夠時,需要我們在給他增加一些規則,否則會產生錯誤,造成編譯錯誤。
當因爲混淆規則而發生錯誤時,我們可以通過gradle的輸出文件來查看到底是哪裏發生了錯誤。這個文件就是/build/outputs/mapping/release/目錄下的usage.txt文件,我們可以通過查看它來確定移除了哪些我們需要用到的代碼。
造成我們所需要的代碼被移除的原因主要是以下三點。
- 當應用引用的類只來自 AndroidManifest.xml 文件時
- 當應用調用的方法來自 Java 原生接口 (JNI) 時
- 當應用在運行時(例如使用反射或自檢)操作代碼時
保留代碼的規則主要有以下幾種:
- 通過指定類的名稱保留指定的類文件和類的成員
-keep {Modiffier} {class_specification}
例子如下
-keep public class com.google.vending.licensing.ILicensingService
- 通過指定類的成員名稱保留指定類的成員
-keepclassmembers {modifier} {class_specification}
例子如下
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
- 通過指定類成員名保留指定的類和類的成員
-keepclasseswithmembers {class_specification}
例子如下
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
- 通過指定類保留指定的類的成員名稱
-keepnames {class_specification}
- 通過指定類成員保護指定的類的成員名稱
-keepclasseswithmembernames {class_specification}
- 通過指定類成員保護指定的類和類的成員名稱(這裏類成員條件必須完全滿足)
-keepclasseswithmembernames {class_specification}
看過這些規則可能就會暈了,因爲記起來十分的繁瑣,但實際上,google也爲我們提供了另一個方法來保留代碼,就是使用註釋的方式,我們可以看到在proguard-android.txt和proguard-android-optimize.txt中都寫有這樣的規則
-keep class android.support.annotation.Keep
-keep @android.support.annotation.Keep class * {*;}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
也就是說,遇到我們想保存的類或者類對象的時候,只添加註釋即可。
但是,這樣用我們需要用到註解支持庫,需要在gradle里加上。
dependencies { compile 'com.android.support:support-annotations:24.2.0' }
資源壓縮
上面講的都是代碼的混淆,但實際上如果已經實現了代碼混淆,我們也可以對資源進行壓縮,只需要再加上一句shrinkResources true即可。
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}