一、问题描述
有以下结构:
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);
});
输出信息如下:
GET_APP_VERSION_INFO-result:{"a":"1.0.1"}
如上“data” 字段被序列化成了“a” 。
二、问题解决过程及原因分析
开始以为字段被优化成了"a"、"b"等,这可能是由于 Gson 库默认启用了字段混淆(Field Naming Policy)功能,将字段名压缩为较短的形式。
尝试使用以下两种方法进行解决:
1、禁用字段混淆
通过设置 Gson 的字段命名策略来禁用字段混淆。可以使用 GsonBuilder
类来创建 Gson 对象,并调用 setFieldNamingPolicy
方法来设置字段命名策略。以下是禁用字段混淆的示例代码:
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.IDENTITY)
.create();
String jsonString = gson.toJson(yourObject);
通过将 FieldNamingPolicy.IDENTITY
作为字段命名策略,字段名将与原始对象中的字段名保持一致,不会被压缩。
2、使用 @SerializedName
注解
如果只想针对特定字段禁用字段混淆,可以在这些字段上使用 @SerializedName
注解,并为注解的值指定原始字段名。
如下:
class YourClass {
@SerializedName("originalFieldName")
private String fieldName;
// ...
}
Gson gson = new Gson();
String jsonString = gson.toJson(yourObject);
通过在字段上使用 @SerializedName
注解,可以指定该字段在序列化为 JSON 字符串时应使用的原始字段名,而不受字段混淆的影响。
然而以上两种方法都没能解决。
突然想到 被优化成了"a"、“b” 有点像打包时开启了 代码混淆,于是果断加上gson 的混淆规则,果然问题得以解决。
三、最终解决方案
加上gson 的混淆规则 ,注意: com.test.demo.NativeParam 需要替换为自己的mode 结构。
#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
测试输出结果如下:
GET_APP_VERSION_INFO-result:{"data":"1.0.1"}