Thursday, May 17, 2012

Configuring ProGuard for an Android project

I've done a few Android projects and I find that when I start pushing out obfuscated binaries often I have to spend quite a bit of time debugging my proguard.conf file to get rid of all the new crashes :)
For this reason I've created this Android proguard.conf generic starting point template. If you've know any other common config lines let's have them and I'll update this post accordingly.

-dontpreverify
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*
-printmapping AppClassMap.map

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-keep class android.support.v4.** { *; }

-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.app.Fragment
-keep public class * implements de.akquinet.android.androlog.reporter.Reporter
-keep class com.google.android.apps.analytics.PipelinedRequester$Callbacks

-keep public class * extends android.view.View {
    public (android.content.Context);
    public (android.content.Context, android.util.AttributeSet);
    public (android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

# Keep serializable classes and necessary members for serializable classes
# Copied from the ProGuard manual at http://proguard.sourceforge.net.
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient ;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * implements android.os.Parcelable {
    static android.os.Parcelable$Creator CREATOR;
}

-keepclassmembers class **.R$* {
    public static ;
}

-keep public interface com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
    native ;
}

-keepclassmembers class * extends java.lang.Enum {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# Removes all calls to Log. Delete the methods you want to keep.
-assumenosideeffects class android.util.Log {
    public static int v(...);
    public static int d(...);
    public static int i(...);
    public static int w(...);
    public static int e(...);
    public static int wtf(...);
}

# Removes all calls to Log. Delete the methods you want to keep.
-assumenosideeffects class de.akquinet.android.androlog.Log {
    public static int v(...);
    public static int d(...);
    public static int i(...);
    public static int w(...);
    public static int e(...);
    public static int wtf(...);
}


-dontwarn **CompatHoneycomb
-dontwarn android.support.v4.**
-dontskipnonpubliclibraryclasses
-dontusemixedcaseclassnames