Gson.toJson 返回 null [ProGuard 问题]

2024-03-24

用户错误报告显示Gson().toJson(obj)偶尔回来{}但对于大多数用户来说它工作正常。

我拜访了一位用户,他遇到了该错误并在他的手机上调试了应用程序,我做了Toast显示发送到服务器的内容,我看到 Toast 显示{}并且Records and ID aren't 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);

but 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);

Database

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();

吐司秀{"Records":[]}.比上限更糟糕的情况永远不会发生

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  ----------

我如何使其对所有用户都正确工作?

Comments

这应该是不可能的,您需要有关 {} 案例的更多详细信息,例如 是否一致,是否由于多线程,是否特定的JDK 版本

没有任何多线程现象。例如,没有Runnable no AsycTask no Thread.它只是一个普通的片段,它从内容提供者获取数据并创建 json 字符串。

建议的解决方案具有相同的结果!

ClassA obj = new ClassA(ID,Records); 
Gson gson = new GsonBuilder().serializeNulls().create();
Toast.makeText(getActivity(), gson.toJson(obj), Toast.LENGTH_LONG).show();

吐司秀{} again.


这是因为ID and Records in ClassA为空。 Gson 默认情况下不会序列化 null,实际上有一个方法可以启用序列化 null,我几乎总是启用该方法:

private static final Gson GSON = new GsonBuilder().serializeNulls().create();

我建议保留一个 Gson 的静态实例,这样您就不必在每次想要序列化时都创建一个实例。

如果您不想序列化空值,则可以使用其他一些选项来修复代码,例如在构造函数中进行空值检查ClassA.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Gson.toJson 返回 null [ProGuard 问题] 的相关文章

随机推荐