Android ProGuard 常用設定 與 Library 衝突解決 (Gson, ActionbarSherlock)

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 下)

參考:http://code.google.com/p/google-gson/source/browse/trunk/examples/android-proguard-example/proguard.cfg

解決 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

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.