Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ProGuard for Android and GSON

I'm setting up ProGuard for my Android project. My project also uses GSON.

I've researched ProGuard configurations for compatibility with GSON and Android and came across this example offered by google-gson https://code.google.com/p/google-gson/source/browse/trunk/examples/android-proguard-example/proguard.cfg.

ProGuard config copied below:

##---------------Begin: proguard configuration common for all Android apps ---------- -optimizationpasses 5 -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers -dontpreverify -verbose -dump class_files.txt -printseeds seeds.txt -printusage unused.txt -printmapping mapping.txt -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*  -allowaccessmodification -keepattributes *Annotation* -renamesourcefileattribute SourceFile -keepattributes SourceFile,LineNumberTable -repackageclasses ''  -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 * extends android.app.backup.BackupAgentHelper -keep public class * extends android.preference.Preference -keep public class com.android.vending.licensing.ILicensingService -dontnote com.android.vending.licensing.ILicensingService  # Explicitly preserve all serialization members. The Serializable interface # is only a marker interface, so it wouldn't save them. -keepclassmembers class * implements java.io.Serializable {     static final long serialVersionUID;     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(); }  # Preserve all native method names and the names of their classes. -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); }  # Preserve static fields of inner classes of R classes that might be accessed # through introspection. -keepclassmembers class **.R$* {   public static <fields>; }  # Preserve the special static methods that are required in all enumeration classes. -keepclassmembers enum * {     public static **[] values();     public static ** valueOf(java.lang.String); }  -keep public class * {     public protected *; }  -keep class * implements android.os.Parcelable {   public static final android.os.Parcelable$Creator *; } ##---------------End: proguard configuration common for all Android apps ----------  ##---------------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.** { *; }  # Application classes that will be serialized/deserialized over Gson -keep class com.google.gson.examples.android.model.** { *; }  ##---------------End: proguard configuration for Gson  ---------- 

Questions:

  1. I see that this file has not been updated since 2011, is it still recommended for use? I ask because Android/GSON has changed quite a bit since then so I don't know how much of the above in unnecessary or incorrect.

  2. If this is not recommended, is there a new recommended ProGuard configuration for GSON in Android?

like image 704
AtariPete Avatar asked May 23 '14 09:05

AtariPete


People also ask

Is ProGuard necessary for Android?

It reduces the size of the application. It removes the unused classes and methods that contribute to the 64K method counts limit of an Android application. It makes the application difficult to reverse engineer by obfuscating the code.

What is ProGuard used for in Android?

ProGuard is a free Java app for Android that allows us to do the following: Reduce (minimize) the code: Unused code in the project should be removed. Code obfuscation: Rename the names of classes, fields, and so on. Improve the code: Inline the functions, for example.

What is ProGuard and R8?

Proguard and R8 both are similar tools that are used for reducing the size of our APK and increase the performance of our APK by shrinking the unused resources.


2 Answers

I think most of those settings you have there are already included in the Android SDK by default.

So you can remove most of them, just leaving in the section devoted to GSON.


I am developing in Eclipse using Android SDK Tools 22.6.3 & whatever version of ProGuard ships with that.

Here's what I'm using for GSON 2.2.4 (as per their example):

##---------------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  # Gson specific classes -keep class sun.misc.Unsafe { *; } #-keep class com.google.gson.stream.** { *; }  # Application classes that will be serialized/deserialized over Gson # -keep class mypersonalclass.data.model.** { *; } 

It looks exactly the same as what you have, except I don't need the line about the annotations.


You can see I've commented out some classes that I added myself. If you serialize/deserialize your own classes, you need to declare them here in place of the reference to mypersonalclass.data.model. This is really important, as you don't want ProGuard to obfuscate the field or class names that GSON uses for serialization.

I always leave those types of comments in there, so I know how to configure the next library or app.

like image 100
Richard Le Mesurier Avatar answered Sep 20 '22 18:09

Richard Le Mesurier


The previous answer stopped working for me recently probably due to some changes in Android (R8 is used now instead of Proguard). The configuration I use now is as follows (source - GSON examples):

##---------------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 -dontwarn sun.misc.** #-keep class com.google.gson.stream.** { *; }  # Application classes that will be serialized/deserialized over Gson -keep class com.google.gson.examples.android.model.** { <fields>; }  # Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory, # JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) -keep class * implements com.google.gson.TypeAdapter -keep class * implements com.google.gson.TypeAdapterFactory -keep class * implements com.google.gson.JsonSerializer -keep class * implements com.google.gson.JsonDeserializer  # Prevent R8 from leaving Data object members always null -keepclassmembers,allowobfuscation class * {   @com.google.gson.annotations.SerializedName <fields>; }  ##---------------End: proguard configuration for Gson  ---------- 

I found out that classes whose fields are annotated by @SerializedName do not have to be explicitly listed unless they are inner classes.

like image 27
Miloš Černilovský Avatar answered Sep 21 '22 18:09

Miloš Černilovský