Gson.toJson返回null,ProGuard问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gson.toJson返回null,ProGuard问题相关的知识,希望对你有一定的参考价值。
用户错误报告显示Gson().toJson(obj)
偶尔返回,但对于大多数用户而言,它可以正常工作。
我访问了一个遇到错误并在手机上调试了应用程序的用户,然后我做出了Toast
以显示向服务器发送的内容,并且我看到Toast显示了以及Records和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
)返回了。没有Web服务问题也没有数据库问题。
额外信息
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();
吐司显示
"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 ----------
我如何使其对所有用户正常工作?
评论
这不可能,您需要有关案例的更多详细信息,例如是否一致,是由于多线程处理,还是特定的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();
吐司再次显示
。
用户错误报告显示Gson()。toJson(obj)偶尔返回,但对于大多数用户而言,它可以正常工作。我拜访过一个遇到错误并在手机上调试过应用程序的用户,我让Toast展示...
[只是我的疯狂猜测,我看到您在注释之一中提到ClassA
和ClassB
是片段内的内部类。因此,也许还有一些可以尝试的东西,如果还没有的话。
这是因为ID
中的Records
和ClassA
为空。 Gson默认情况下不会序列化null,实际上有一种启用序列化null的方法,我几乎总是启用它:
ArrayList<ClassB> Records= new ArrayList<>();
ClassA obj = new ClassA(null,Records);
Toast.makeText(getApplicationContext(),new Gson().toJson(obj
),Toast.LENGTH_LONG).show();
在您的代码中,需要指出一些有趣的事情:
感谢@Montri M的不错建议:
您可能在某处捕获了JsonParseException
吗?当没有在RuntimeTypeAdapterFactory中注册类型时,TypeAdapter
有时会引起麻烦。尝试指挥RuntimeTypeAdapterFactory
类,并在项目使用的版本中,替换每次出现的>>
if (delegate == null)
throw new JsonParseException("cannot deserialize " + baseType + " subtype named "
+ label + "; did you forget to register a subtype?");
尝试一下
以上是关于Gson.toJson返回null,ProGuard问题的主要内容,如果未能解决你的问题,请参考以下文章
Gson toJson 返回 JSON 字符串而不是 JSON 对象