Android: What Are the Recommended Configurations for Proguard

Android: What are the recommended configurations for Proguard?

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 Enabling ProGuard in Eclipse for Android 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();
#}

What are the recommended proguard settings for android support library?

The Support Library uses the consumerProguardFiles feature to automatically include the appropriate ProGuard if you're using Gradle, meaning you don't need to manually include anything.

Looking at the ProGuard file for preferences-v7 (stored in the proguard.txt file within the AAR), it contains the following lines:

# Preference objects are inflated via reflection
-keep public class android.support.v7.preference.Preference {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keep public class * extends android.support.v7.preference.Preference {
public <init>(android.content.Context, android.util.AttributeSet);
}

Which covers the exact method that it says you are missing (as PreferenceCategory indirectly extends Preference). Check to make sure you are using the full Gradle dependency.

ProGuard - How to use correctly for Android ? Which classes and libraries to keep?

Question 1: Should I obfuscate above libraries?

Yes. If you add -keep <library> rules then the entire library will be included in your APK, which bloats it and might cause problems such as making your app exceed the 64k method limit and require Multidex. It's always a good idea to apply the ProGuard rules provided by the library. You can usually find .pro files in the libraries source code or in websites such as https://github.com/krschultz/android-proguard-snippets.

Question 2: Is it ok to keep the class names which are mentioned in AndroidManifest.xml and specifically their public members, and let obfuscate rest of the code.

The Android plugin already does that for you. The plugin scans all classes whose names need to be preserved (e.g. Activities, Services, BroadcastReceivers, Views, etc) and doesn't obfuscate them. This includes everything that you declare in AndroidManifest.xml.

What are the recommended ProGuard rules for Smack 4.1?

What are the proper Proguard rules for Smack 4.1 when building an
Android release apk?

Depends on what "proper" means for you.

The easiest way is likely to tell ProGuard to keep all classes and interfaces of Smack.

-keep class org.jivesoftware.smack.** { *; }
-keep class org.jivesoftware.smackx.** { *; }

Alternatively you can configure ProGuard so that it only keeps those parts of Smack that you actually use, and let ProGuard strip everything else. But to do so, you'll need a good understanding how your App uses Smack. See for example the ProGuard configuration of MAXS's Transport XMPP: https://bitbucket.org/projectmaxs/maxs/src/75efeba8d8470b89da8cd8551304bb00648e4945/transport-xmpp/proguard-project.txt?at=master#cl-20

Note that if you don't know exactly what are you doing, then Smack could behave unexpectedly or even crash. Only fine tune ProGuard if you know what you are doing!

Howto configure ProGuard settings for ButterKnife 8?

In ButterKnife 8 the auto generated Subclasses are called different. You can handle ProGuard settings for Version 7 and 8 this way:

###---------------Begin: proguard configuration for ButterKnife  ----------
# For Butterknife:
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**

# Version 7
-keep class **$$ViewBinder { *; }
# Version 8
-keep class **_ViewBinding { *; }

-keepclasseswithmembernames class * { @butterknife.* <fields>; }
-keepclasseswithmembernames class * { @butterknife.* <methods>; }
###---------------End: proguard configuration for ButterKnife ----------

Although I am using @OnClick methods I even do not need the last line. These settings work perfect for me. Try it out!



Related Topics



Leave a reply



Submit