Mr.*_*.AF 6 java android json gson
用户错误报告显示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;
}
}
Run Code Online (Sandbox Code Playgroud)
在这里我做序列化对象
ClassA obj = new ClassA(ID,Records);
String json = new Gson().toJson(obj);
Run Code Online (Sandbox Code Playgroud)
但是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);
Run Code Online (Sandbox Code Playgroud)
数据库
id | data
----------------
c89 | {"ID":"c89","Records":[{"T":0,"F":0,"D":"2019/04/11 05:48 PM"}]} correct one
c90 | {} bug
Run Code Online (Sandbox Code Playgroud)
空输入测试
我做了下面的测试,我发现问题超出了空输入
ArrayList<ClassB> Records= new ArrayList<>();
ClassA obj = new ClassA(null,Records);
Toast.makeText(getApplicationContext(),new Gson().toJson(obj ),Toast.LENGTH_LONG).show();
Run Code Online (Sandbox Code Playgroud)
Toast 显示{"Records":[]}.worse than upper condition 永远不会发生
还有 IDE 说
if(ID!=null && Records!=null) <= this condition is always true
ClassA obj = new ClassA(ID,Records);
Run Code Online (Sandbox Code Playgroud)
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 ----------
Run Code Online (Sandbox Code Playgroud)
我如何使它对所有用户都能正常工作?
注释
这应该是不可能的,您需要有关 {} 情况的更多详细信息,例如它是否一致、是否由于多线程、是否为特定的 JDK 版本
没有任何多线程phenomena.for例如,没有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();
Run Code Online (Sandbox Code Playgroud)
吐司{}再次出现。
这是因为ID和RecordsinClassA为空。Gson 默认情况下不会序列化 null,实际上有一个方法可以启用序列化 null,我几乎总是启用该方法:
private static final Gson GSON = new GsonBuilder().serializeNulls().create();
Run Code Online (Sandbox Code Playgroud)
我建议保留一个 Gson 的静态实例,这样您就不必在每次想要序列化时都创建一个实例。
如果您不想序列化 null,则可以使用其他一些选项来修复代码,例如在 的构造函数中进行 null 检查ClassA。
| 归档时间: |
|
| 查看次数: |
1871 次 |
| 最近记录: |