1. Problem description
Has the following structure:
public class NativeParam<T> {
private T data;
public NativeParam(T data) {
this.data = data;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
};
NativeParam<String> data = "1.0.1";
String result = gson.toJson(new NativeParam<>("1.0.1"));
log.i(TAG,"GET_APP_VERSION_INFO-result:" + result);
});
The output information is as follows:
GET_APP_VERSION_INFO-result:{"a":"1.0.1"}
As shown above, the "data" field is serialized into "a".
2. Problem solving process and cause analysis
At first I thought that the fields were optimized into "a", "b", etc. This may be because the Gson library enables the field obfuscation (Field Naming Policy) function by default to compress the field names into a shorter form.
Try the following two methods to resolve:
1. Disable field obfuscation
Disable field obfuscation by setting Gson's field naming policy. You can use GsonBuilder
the class to create a Gson object and call setFieldNamingPolicy
the method to set the field naming strategy. Here is sample code to disable field obfuscation:
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
.create();
String jsonString = gson.toJson(yourObject);
By using FieldNamingPolicy.IDENTITY
as the field naming strategy, the field names will remain consistent with the field names in the original object and will not be compressed.
2. Use @SerializedName
annotations
If you want to disable field obfuscation only for specific fields, you can use an annotation on those fields @SerializedName
and specify the original field name for the annotation's value.
as follows:
class YourClass {
@SerializedName("originalFieldName")
private String fieldName;
// ...
}
Gson gson = new Gson();
String jsonString = gson.toJson(yourObject);
By using the annotation on a field @SerializedName
, you can specify the original field name that the field should use when serialized to a JSON string, without being affected by field obfuscation.
However, the above two methods failed to solve the problem.
Suddenly I thought that being optimized into "a" and "b" was a bit like turning on code obfuscation during packaging, so I decisively added gson's obfuscation rules, and the problem was solved.
3. Final solution
In addition to gson's obfuscation rules, note: com.test.demo.NativeParam needs to be replaced with your own mode structure.
#gson start
# custom 不能混淆的要加上
# Application classes that will be serialized/deserialized over Gson
-keep class com.test.demo.NativeParam { *; }
#gson start
-keep class com.google.gson.** {*;}
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken
-keep class com.google.** {
<fields>;
<methods>;
}
-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();
}
-dontwarn com.google.gson.**
#gson end
The test output results are as follows:
GET_APP_VERSION_INFO-result:{"data":"1.0.1"}