今天決定對項目使用混淆工具proguard。因而便開始找proguard究竟放在sdk的什麼地方,果不其然,我在sdk目錄的tools文件夾中找到了proguard的文件夾。
配置方法這裏簡單的說明一下。
打開要混淆的android項目,找到project.properties文件。
後面添加上proguard.config=android.pro
如今我來解釋說明一下這句話,後面的android.pro是proguard的配置文件,主要是告訴proguard應該怎麼混淆文件。那麼這個配置文件在哪裏呢?
網上都是直接複製的,沒有追其根源。咱們能夠在前面提到的proguard的文件夾裏面,找到proguard-android.txt。這個是默認的混淆配置,已經針對android的代碼作了優化了,可是並無添加咱們本身的混淆邏輯。 java
這個文件就是我後面的android.pro。我是這麼作的,把該文件複製到項目中,而後修更名字爲android.pro。
所以也就是告訴各位這個文件的名字沒有硬性要求的,只要是正確的配置文件就能夠了。 android
以後就開始立馬簽名文件了,而後本身反編譯文件,發現裏面都是abcd的類名,不禁得很開心。 json
以後立馬開始安裝,果真就開始報錯了。這裏咱們要分析錯誤的來源,才能正確開始添加咱們本身編寫的的配置代碼到配置文件中。有些機子是直接就死機的,那麼咱們沒法看到錯誤報告,有些是有系統自帶report的報告,咱們能夠看到相關的堆棧錯誤。那麼怎麼解決直接死機崩潰,沒有堆棧日誌的狀況呢?咱們能夠鏈接機子到電腦,在eclipse中看到設備,而後讓它死機,那麼咱們一樣能夠再logcat中看到死機的緣由。 服務器
這裏要搞清楚,咱們不是debug模式,所以報出的錯誤都是這樣的 app
後面是unkonw source。由於咱們沒有關聯相關的代碼,所以是和開發模式是不一樣的,是看不到具體在第幾行的。不過好在咱們能夠知道是什麼方法的名字出現了異常。所以咱們能夠反編譯混淆過的代碼,查看和對比沒有混淆的代碼。發現問題所在,接下來咱們才能夠添加咱們本身的混淆配置。接下來,我要舉例說明遇到的問題,和解決的思路,供你們參考。 框架
1.解決案例一:下面看一下部分的代碼。 eclipse
public abstract class Model { @Column(name = "Id") private Long mId = null; //下面這個函數是另外一個類裏面的 private Field getIdField(Class<?> type) { if (type.equals(Model.class)) { try { return type.getDeclaredField("mId"); } catch (NoSuchFieldException e) { Log.e("Impossible!", e); } } else if (type.getSuperclass() != null) { return getIdField(type.getSuperclass()); } return null; }
若是咱們直接的混淆的話,那麼mId確定會變成了abcd之類的詞彙。
而在下面的方法中出現了反射方法。 ide
type.getDeclaredField("mId");
那麼咱們在混淆以後確定會報錯的。而且返回一個null,筆者當時就是報了個空指針異常,程序的主要做用是查找指定類,發現它的id,並把具備該性質的類放入集合中。
很好,咱們發現了這個錯誤。下面咱們就開始添加以下的配置:
-keepclassmembernames class *******************.Model{
java.lang.Long mId;
}
上面的一連串*號是個人包名。
筆者一開始是這麼寫的。
-keepclassmembernames class *******************.Model{
Long mId;
}
後來查看了proguard文件夾下面examples文件夾下面的許多pro文件,發現了他們的共性,發現不是基本類型是不能這麼寫的。 函數
後來在混淆以後,在項目中發現了這麼個文件夾proguard。這個文件夾是混淆過程當中產生的相關的日誌文件。
你們能夠再mapping.txt文件中找到proguard究竟給你混淆了什麼,同時保留了什麼。我對上面的Model類嘗試了搜索,看看mId是否是混淆了,仍是說保留了。 工具
***********.Model -> com.a.d:
java.lang.Long mId -> mId
結果搜索到這些語句
能夠看到Model類已經被混淆成com.a.d了。而咱們但願保留的mId,也確實沒有混淆了。
2.解決案例二:
因爲筆者的項目使用了fastjson框架,發如今解析從服務器下來的數據的時候發生了異常。
你們都知道json數據裏面的成員變量是有具體的含義的,好比{username:'xiaoming',password:'dddddddd'};
而我本身寫的model,裏面對應的username確定是混淆的。所以咱們要解析json數據,確定是不但願它被混淆的。
所以咱們能夠在配置文件中添加以下:
-keep class com.xxxx.json.model.**{
*;
}
把json包下的實體類所有保留。
上面描述了兩個解決案例:更多的配置例子能夠查看sdk的proguard文件夾下面的examples目錄。
接下來解釋幾個配置參數加深你們對proguard的配置的理解:
保留全部的本地native方法不被混淆。這點在咱們作ndk開發的時候很重要。
-keepclasseswithmembernames class * {
native <methods>;
}
保留全部的set和get開頭的方法。
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
咱們保留在activity中的方法參數是view的方法,這樣的話,咱們在xml裏面編寫onClick就不會被影響了。
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
接下來附上相關的proguard的配置解釋,是筆者從網上搜羅的。
-keepclasseswithmembers 指定的類和類成員被保留,假如指定的類成員存在的話