一、问题描述
有以下结构:
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"}