Android: What are the recommended configurations for Proguard?

AndroidProguard

Android Problem Overview


I'm developing apps for Android and using Proguard to obfuscate the code.

Currently i'm using ProGuard configurations:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-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 public class com.android.vending.licensing.ILicensingService

To maintain custom components names that are used on layouts XML:

-keep public class custom.components.**

To remove debug logs:

-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}

To avoid changing names of methods invoked on layout's onClick:

-keepclassmembers class * {
 public void onClickButton1(android.view.View);
 public void onClickButton2(android.view.View);
 public void onClickButton3(android.view.View);
}

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

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

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

The question is (are):

Are any other tags recommended? Why and what for?

It's possible to make a comment on a proguard.cfg file? I would like to have it with comments for what some lines are doing so that other developers don't have doubts about why i added.

Also in proguard, is it possible to maintain the comment header of a file (with the copyright)? If it's not, or it's not a good policy where should i add the copyright?

Android Solutions


Solution 1 - Android

Android SDK (r20 or higher)

Please check the predefined proguard.config refered in project.properties

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt

More info: http://proguard.sourceforge.net/manual/examples.html#androidapplication

Here you can check a proguard "default" file that I keep updating: https://medium.com/code-procedure-and-rants/android-my-standard-proguard-ffeceaf65521


Android SDK (r19 or lower)

Based on my answer https://stackoverflow.com/questions/4732656/enabling-proguard-in-eclipse-for-android/5040675#5040675 I've ended up with this generic file. I've added comments to remember what each line is for. It might help people out there so here it is:

-optimizationpasses 5

#When not preverifing in a case-insensitive filing system, such as Windows. Because this tool unpacks your processed jars, you should then use:
-dontusemixedcaseclassnames

#Specifies not to ignore non-public library classes. As of version 4.5, this is the default setting
-dontskipnonpubliclibraryclasses

#Preverification is irrelevant for the dex compiler and the Dalvik VM, so we can switch it off with the -dontpreverify option.
-dontpreverify

#Specifies to write out some more information during processing. If the program terminates with an exception, this option will print out the entire stack trace, instead of just the exception message.
-verbose

#The -optimizations option disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle. Note that the Dalvik VM also can't handle aggressive overloading (of static fields).
#To understand or change this check http://proguard.sourceforge.net/index.html#/manual/optimizations.html
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

#To repackage classes on a single package
#-repackageclasses ''

#Uncomment if using annotations to keep them.
#-keepattributes *Annotation*

#Keep classes that are referenced on the AndroidManifest
-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 public class com.android.vending.licensing.ILicensingService


#To remove debug logs:
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}

#To avoid changing names of methods invoked on layout's onClick.
# Uncomment and add specific method names if using onClick on layouts
#-keepclassmembers class * {
# public void onClickButton(android.view.View);
#}

#Maintain java native methods 
-keepclasseswithmembernames class * {
    native <methods>;
}

#To maintain custom components names that are used on layouts XML.
#Uncomment if having any problem with the approach below
#-keep public class custom.components.package.and.name.**

#To maintain custom components names that are used on layouts XML:
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

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

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

#Maintain enums
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

#To keep parcelable classes (to serialize - deserialize objects to sent through Intents)
-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

#Keep the R
-keepclassmembers class **.R$* {
    public static <fields>;
}

###### ADDITIONAL OPTIONS NOT USED NORMALLY

#To keep callback calls. Uncomment if using any
#http://proguard.sourceforge.net/index.html#/manual/examples.html#callback
#-keep class mypackage.MyCallbackClass {
#   void myCallbackMethod(java.lang.String);
#}

#Uncomment if using Serializable 
#-keepclassmembers class * implements java.io.Serializable {
#    private static final java.io.ObjectStreamField[] serialPersistentFields;
#    private void writeObject(java.io.ObjectOutputStream);
#    private void readObject(java.io.ObjectInputStream);
#    java.lang.Object writeReplace();
#    java.lang.Object readResolve();
#}

Solution 2 - Android

For standard builds with Ant or Eclipse, the Android SDK (r20 or higher) already provides a suitable configuration, referenced by the property proguard.config in the file project.properties (as Michal points out in his answer). In older releases, you always had to specify your own complete configuration, so older advice (like the first answer) can lead to some confusion.

For custom builds, you can find the latest recommended configuration in the ProGuard manual > Examples > A complete Android application. The Proguard distribution also contains a sample file examples/android.pro

Notably, you may want to preserve annotations, and setters in View extensions.

You can add comments after a hash character '#', as extensively done in the sample files.

Solution 3 - Android

In your project file called project.properties, set following value:

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt

This will take the latest version of Proguard settings from Android SDK.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionneteinsteinView Question on Stackoverflow
Solution 1 - AndroidneteinsteinView Answer on Stackoverflow
Solution 2 - AndroidEric LafortuneView Answer on Stackoverflow
Solution 3 - AndroidMichalView Answer on Stackoverflow