GSON uses reflection to determine the names of the attributes in the serialized JSON representation of your objects. If you obfuscate the names of class attributes, you will end up with JSON that contains obfuscated names as well. So instead of having`{ "name": "John", "last_name": "Smith" }` the serialized object will look like `{ "a0": "John", "a1": "Smith" }`.
What further complicates the matter is that by default ProGuard and R8 will generate a different name for every class and attribute with every build. This means that the next versions of your app will not be able to read objects serialized by the previous versions.
Usually both of the effects above are not desirable. This means that in your code you will want to keep serialized class members from being obfuscated. It is a good idea to have a common factor for your serialized classes, which you can use for targeting - for example an annotation, like this:
-keep @com.mycompany.dataclass public class *
In many cases you are going to be using Expose and/or SerializedName annotations in your classes to limit serialized attributes and define their names. If you do, you can use the following rule set:
-dontnote com.google.gson.annotations.Expose
-keepclassmembers class * {
@com.google.gson.annotations.Expose <fields>;
}
-keepclasseswithmembers,allowobfuscation,includedescriptorclasses class * {
@com.google.gson.annotations.Expose <fields>;
}
-dontnote com.google.gson.annotations.SerializedName
-keepclasseswithmembers,allowobfuscation,includedescriptorclasses class * {
@com.google.gson.annotations.SerializedName <fields>;
}
One particular case is enum values. To handle them correctly add SerializedName annotation to the enum values and use the rule like this:
In your source code:
public enum Animal {
@SerializedName("kangaroo")
Kangaroo,
@SerializedName("lion")
Lion
}
In your ProGuard configuration:
-keepclassmembers enum * {
@com.google.gson.annotations.SerializedName <fields>;
}