Android Apps 主要由 Java 編寫,編譯 (Compile) 時先由 Java Code Compile 成 Java Bytecode,然後再變成 Dalvik Bytecode。
由於 Bytecode 對比 Machine Code 較易被反編譯 (Decompile),
反編譯後甚至連 Variable 及 Class 的名稱都不變,造成 Apps 較易被破解及盜用。
因此 Java 程式發佈通常使用 Obfuscator 把 Bytecode 的 Variable, Class 名稱及邏輯變得難以理解。
Obfuscator 有很多種,但 Android 的世界主要使用 Proguard (其實它還具有Optimizer等功能),
而且它已經被整合進 Android build system,所以只要簡單設定就可以使用(但不代表成功使用…)。
啟用 ProGuard
在 project.properties 加入 proguard.config 的設定,例如:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
會先指定 SDK 目錄中的 proguard-project.txt,再用本地的 Override 之。
之後使用 Eclipse 的 Android > Export 或使用 ANT 等 Build 即會使用 ProGuard (Eclipse 直接 Run 不會)
啟用 ProGuard Optimization
Android SDK 的 default preset 沒有啟用 Optimization,如果需要啟用則再次修改 proguard.config 如下:
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
移除 Log.* Debug Message
只移除 Log.d 及 Log.v
-assumenosideeffects class android.util.Log { public static *** d(...); public static *** v(...); }
移除全部 Log.*
-assumenosideeffects class android.util.Log { *; }
解決 Gson 被 Obfuscated 後會出現 ClassCastException
java.lang.ClassCastException: com.google.gson.internal.StringMap cannot be cast to com.tigerworkshop.responses.SomeResponse
因為 Gson 類似 gson.fromJson(json, SomeResponse.class) 會用 static reference 到某些 Class,
而那些 Class 的 Signature 被刪掉,Class Name都改掉了。
解決方法是在 proguard-project.txt 加入以下設定,叫 ProGuard 不要搞亂 Gson 的東西:
##---------------Begin: proguard configuration for Gson ---------- # Gson uses generic type information stored in a class file when working with fields. Proguard # removes such information by default, so configure it to keep all of it. -keepattributes Signature # For using GSON @Expose annotation -keepattributes *Annotation* # Gson specific classes -keep class sun.misc.Unsafe { *; } #-keep class com.google.gson.stream.** { *; } -keep class com.tigerworkshop.responses.** { *; } ##---------------End: proguard configuration for Gson ----------
(需要 fromJson 的 Class 都放了在 com.tigerworkshop.responses 下)
解決 ActionbarSherlock 被 Obfuscated 後會出現 NoSuchMethodException
java.lang.RuntimeException: java.lang.NoSuchMethodException: <init> [class android.app.Activity, int]
解決方法是在 proguard-project.txt 加入以下設定
##---------------Begin: proguard configuration for Actionbar Sherlock ---------- -keep class android.support.v4.app.** { *; } -keep interface android.support.v4.app.** { *; } -keep class com.actionbarsherlock.** { *; } -keep interface com.actionbarsherlock.** { *; } -keepattributes *Annotation* ##---------------End: proguard configuration for Actionbar Sherlock ----------
參考: http://actionbarsherlock.com/faq.html