【发布时间】:2020-03-02 08:30:05
【问题描述】:
用户错误报告显示Gson().toJson(obj) 偶尔会返回{},但对于大多数用户来说它工作正常。
我拜访了一位用户,他在手机上遇到了错误并调试了应用程序,我制作了Toast 来显示正在发送到服务器的内容,我看到了 Toast 显示 {} 以及 记录 和ID 不是 null。
这就是我所做的。
private class ClassA{
String ID;
ArrayList<ClassB> Records;
ClassA(String ID, ArrayList<ClassB> Records) {
this.ID= ID;
this.Records= Records;
}
}
private class ClassB {
int T;
int F;
String D;
ClassB (int T, int F, String D) {
this.T= T;
this.F = F;
this.D= D;
}
}
我在这里序列化对象
ClassA obj = new ClassA(ID,Records);
String json = new Gson().toJson(obj);
但new Gson().toJson(obj) 对于某些用户可以正常工作,但对于某些用户返回 {}
服务器数据库显示一些用户发送了数据{},但一些正确的 json。经过一些研究我发现new Gson().toJson(obj) 返回{}。没有网络服务问题,也没有数据库问题。
额外信息
ArrayList<ClassB> Records= new ArrayList<>();
Records.add(new ClassB(Integer.valueOf(t.toString()), Integer.valueOf(f.toString()),d.toString()));
ClassA obj = new ClassA(ID,Records);
String json = new Gson().toJson(obj);
数据库
id | data
----------------
c89 | {"ID":"c89","Records":[{"T":0,"F":0,"D":"2019/04/11 05:48 PM"}]} correct one
c90 | {} bug
空输入测试
我做了下面的测试,我发现问题超出了空输入
ArrayList<ClassB> Records= new ArrayList<>();
ClassA obj = new ClassA(null,Records);
Toast.makeText(getApplicationContext(),new Gson().toJson(obj ),Toast.LENGTH_LONG).show();
Toast 显示 {"Records":[]}.worse 比上限条件永远不会发生
IDE 也说
if(ID!=null && Records!=null) <= this condition is always true
ClassA obj = new ClassA(ID,Records);
proguard-rules.pro
##---------------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 ----------
我如何使它对所有用户都正常工作?
评论
这应该是不可能的,您需要有关 {} 案例的更多详细信息,例如 是否一致,是否由于多线程,是否是特定的 JDK 版本
没有任何多线程现象。例如,没有Runnable没有AsycTask没有Thread。它只是一个从内容提供者获取数据并创建json字符串的普通片段。
建议的解决方案具有相同的结果!
ClassA obj = new ClassA(ID,Records);
Gson gson = new GsonBuilder().serializeNulls().create();
Toast.makeText(getActivity(), gson.toJson(obj), Toast.LENGTH_LONG).show();
Toast 再次显示{}。
【问题讨论】:
-
尝试将
getters添加到两个类中 -
这应该是不可能的,您需要有关
{}案例的更多详细信息,例如是否一致,是否由于多线程,是否为特定的 JDK 版本。 -
这看起来应该作为错误报告发布到 Gson 项目。但是,他们会要求您提供比这里更多的信息。请注意。
-
@KarolDowbecki 这不是多线程
-
您应该遵循 Java 命名约定:变量名称应该用驼峰命名,例如
Records应该是records,ID应该是id和T,F和D应该分别是t,f和d。