混淆器通過刪除從未用過的代碼和使用簡單名字重命名類、欄位和方法,對代碼進行壓縮,優化和混淆。結果是一個比較小的.apk檔,該檔比較難進行逆向工程。因此,當你的應用程式對安全敏感(要求高),例如當你授權應用程式的時候,混淆器是一種重要的保護手段。
混淆器被集成在android 構建系統中,所以你不必手動調用它。同時混淆器僅在發佈模式下進行構建應用程式的時候才會運行起來,所以在調試模式下構建程式時,你不必處理混淆代碼。讓混淆器運行起來是可選擇的,但是推薦選上。
這個文檔描述了怎樣啟用並配置混淆器,以及使用跟蹤(retrace)工具對混淆的堆疊跟蹤資訊(stack traces)進行解碼。
啟用混淆器Enabling ProGuard
當你新建了一個Android工程之後,一個proguard.cfg檔會在工程的根目錄下自動創建。這個檔定義了混淆器是怎樣優化和混淆你的代碼的,所以懂得怎樣根據你的需要來定制是非常重要的。缺省的配置檔僅覆蓋到了通常情況,所以根據你的需求,很可能需要編輯它。接下來的內容是關於通過定制混淆器配置檔來對混淆器配置。
為了讓啟用混淆器作為Ant或者Eclipse構建過程中一部分,可以在<project_root>/default.properties檔中,設置proguard.config屬性。路徑可以是絕對路徑或者工程根目錄的相對路徑。
如果你讓proguard.cfg檔在缺省位置(工程的根目錄),你可以像這樣指定位置:
proguard.config=proguard.cfg
同樣,你可以把該檔放到任意的位置,並指定它的絕對路徑。
proguard.config=/path/to/proguard.cfg
當你在發佈模式下,或者通過運行ant release,或者通過使用Eclipse中的Export Wizard構建你的應用程式的時候,構建系統都會自動地去檢查proguard.config屬性是否被設置了。如果被設置了,混淆器在把所有東西打包成.apk檔之前,自動地對應用程式位元組碼進行混淆處理。而在調試模式中構建則不會調用混淆器,因為那樣調試會更加繁重。
運行混淆器之後輸出的檔有:
dump.txt
描述.apk包中所有class檔的內部結構。
mapping.txt
列出了源代碼與混淆後的類,方法和屬性名字之間的映射。這個檔對於在構建之後得到的bug報告是有用的,因為它把混淆的堆疊跟蹤資訊反翻譯為源代碼中的類,方法和成員名字。更多資訊,查看解碼混淆過的堆疊跟蹤資訊。
seeds.txt
列出那些未混淆的類和成員。
usage.txt
列出從.apk中剝離的代碼。
這些檔放在以下目錄中:
<project_root>/bin/proguard 當你使用Ant時
<project_root>/proguard 當你使用Eclipse時
注意: 每次在發佈模式下構建時,這些檔都會被最新的檔覆蓋。所以每次發佈程式時候,為了反混淆來自構建時產生的bug報告,請保存這些檔的一個拷貝。對於為什麼要保存這些檔的重要性的更多資訊,請查看程式發佈調試注意事項。
混淆器配置(Configuring ProGuard)
某些情況下,proguard.cfg檔的缺省配置可以滿足需求了。但是,對於混淆器來說,大多數情況做出正確的分析是困難的,並且它或許會刪除在它看來是無用的,但對於程式來說卻確實需要的代碼。一些例子如下:
一個僅引用於AndroidManifest.xml文件的類。
一個通過JNI調用的方法。
動態引用的屬性和方法。
缺省的proguard.cfg檔試圖覆蓋普通的情況,但是你可能碰到類似ClassNotFoundException的異常,這個異常出現在當你的程式去訪問一個被混淆器移除了的類的時候。
你可以在proguard.cfg檔中添加-keep這一行來修復這些錯誤。例如:
-keep public class <MyClass>
-Keep設置有很多可選項和注意地方,所以為了獲得更多關於配置資訊,強烈推薦你閱讀混淆器用戶手冊。特別有用的有Keep選項綜述和舉例部分。在混淆器手冊問題解決方案部分,介紹了代碼在混淆過程中你可能碰到的其他常見問題。
解碼混淆過的堆疊跟蹤資訊(Decoding Obfuscated Stack Traces)
當混淆代碼並輸出了一個堆疊調試資訊時,這些方法名字是混淆過的,雖然可以進行調試,但是調試變得困難。幸運的是,每當混淆器運行時候,它都會輸出到檔<project_root>/bin/proguard/mapping.txt中,該檔包含了從原始類,方法和屬性名字到混淆後名字的映射。
Windows系統中retrace.bat腳本命令或者Linux和Mac OS X系統中retrace.sh腳本命令能把混淆後的堆疊調試資訊轉換為可以理解的檔。它被放在<sdk_root>/tools/proguard/目錄下。運行retrace工具的命令語法是:
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
例如:
retrace.bat -verbose mapping.txt obfuscated_trace.txt
如果你沒有為<stracktrace_file>指定值,那麼retrace工具從標準輸入讀取。
已發佈應用程式的調試注意事項(Debugging considerations for published applications)
保存好每一個已發佈給用戶的程式的mapping.txt文件。通過保存發佈構建版本的mapping.txt檔拷貝,確保當用戶碰到bug,並把混淆後的堆疊調試跟蹤資訊提交給你時,你可以進行調試從而修復問題。程式的mapping.txt檔在每次發佈構建時都會被覆蓋,所以你一定要注意保存正確的版本。
例如,假設你已經發佈了一個應用程式並在繼續在新的版本中開發添加新的功能。接著你馬上啟動混淆器並創建一個新的發佈版本。該操作把mapping.txt文件覆蓋了。一個用戶提交了來自當前發佈版本的bug報告,該報告包含了堆疊調試資訊。你再也不能對用戶的堆疊資訊進行調試了,因為這個對應用戶本機上版本的mapping.txt文件不存在了。其他覆蓋mapping.txt檔的情況還有很多,所以對於每一個可能需要調試的版本,你都要確保有一份拷貝。
如何保存mapping.txt文件由你決定。例如,你可以根據版本和構建號來重命名它們,或者連同你的源代碼進行版本控制。
from
http://www.cnblogs.com/over140/archive/2011/04/22/2024528.html
http://developer.android.com/guide/developing/tools/proguard.html
作業, 此時解決方式如下:
1. 如果程式沒有一定需要使用 Andorid4 提供的class, 則可刪除專案內 libs/android-support-v4.jar 檔.
2. 若不刪除, 則可在 proguard 加入下參數參數
-libraryjars libs/android-support-v4.jar
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment
類似的錯誤訊息:
Proguard returned with error code 1. See console
Unexpected error while evaluating instruction:
Class = [android/support/v4/view/AccessibilityDelegateCompat$AccessibilityDelegateJellyBeanImpl]
Method = [newAccessiblityDelegateBridge(Landroid/support/v4/view/AccessibilityDelegateCompat;)Ljava/lang/Object;]
Instruction = [18] areturn
Exception = [java.lang.IllegalArgumentException] (Can't find any super classes of [android/support/v4/view/AccessibilityDelegateCompatIcs$1] (not even immediate super class [android/view/View$AccessibilityDelegate]))