[ProGuard](http://proguard.sourceforge.net/)?是一個在Android項目中廣泛使用的壓縮和混淆打包的源碼的工具。
你是否使用ProGuard取決你項目的配置,當你構建一個release版本的apk時,通常你應該配置gradle文件。
~~~
buildTypes {
debug {
minifyEnabled false
}
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles 'proguard-rules.pro'
}
}
~~~
為了決定哪些代碼應該被保留,哪些代碼應該被混淆,你不得不指定一個或多個實體類在你的代碼中。 這些實體應該是指定的類包含main方法,applets,midlets,activities,等等。 Android framework 使用一個默認的配置文件,可以在`SDK_HOME/tools/proguard/proguard-android.txt`?目錄下找到。自定義的工程指定的 project-specific 混淆規則,如在`my-project/app/proguard-rules.pro`中定義, 會被添加到默認的配置中。
關于 ProGuard 一個普遍的問題,是看應用程序是否崩潰并報`ClassNotFoundException`?或者?`NoSuchFieldException`?或類似的異常, 即使編譯是沒有警告并運行成功。 這意味著以下兩種可能:
1. ProGuard 已經移除了類,枚舉,方法,成員變量或注解,考慮是否是必要的。
2. ProGuard 混淆了類,枚舉,成員變量的名稱,但是這些名字又被拿原始名稱使用了,比如通過Java的反射。
檢查`app/build/outputs/proguard/release/usage.txt`文件看有問題的對象是否被移除了。 檢查`app/build/outputs/proguard/release/mapping.txt`?文件看有問題的對象是否被混淆了。
In order to prevent ProGuard from?_stripping away_?needed classes or class members, add a?`keep`?options to your proguard config: 以防 ProGuard?_剝離_?需要的類和類成員,添加一個?`keep`選項在你的 proguard 配置文件中:
~~~
-keep class com.futurice.project.MyClass { *; }
~~~
防止 ProGuard?_混淆_?一些類和成員,添加?`keepnames`:
~~~
-keepnames class com.futurice.project.MyClass { *; }
~~~
查看[this template's ProGuard config](https://github.com/futurice/android-best-practices/blob/master/templates/rx-architecture/app/proguard-rules.pro)?中的一些例子。 更多例子請參考[Proguard](http://proguard.sourceforge.net/#manual/examples.html)。
**在構建項目之初,發布一個版本**?來檢查ProGuard規則是否正確的保持了重要的部分。 同時無論何時你添加了新的類庫,做一個發布版本,同時apk在設備上跑起來測試一下。 不要等到你的app要發布 "1.0"版本了才做版本發布,那時候你可能會碰到好多意想不到的異常,需要一些時間去修復他們。
**Tips**每次發布新版本都要寫?`mapping.txt`。每發布一個版本,如果用戶遇到一個bug,同時提交了一個混淆過的堆棧跟蹤。 通過保留`mapping.txt`文件,來確定你可以調試的問題。
**DexGuard**?若果你需要核心工具來優化,和專門混淆的發布代碼,考慮使用[DexGuard](http://www.saikoa.com/dexguard), 一個商業軟件,ProGuard 也是有他們團隊開發的。 它會很容易將Dex文件分割,來解決65K個方法限制問題。