【问题标题】:Gson Exception on deserialize (no-args constructor does not exist)反序列化时的 Gson 异常(不存在无参数构造函数)
【发布时间】:2012-11-02 09:05:49
【问题描述】:

我遇到了一个问题,该问题仅出现在 5000 台设备中的 10 台中。用我的模拟器和测试设备不可能重现它。这似乎是一个非常具体的问题,只有少数设备。我所拥有的只是堆栈跟踪和我的代码。所以我正在针对黑洞进行开发,只有在我在 GooglePlay 上发布了新版本之后,我才能查看这些更改是否解决了问题。我刚刚将新版本更新到 GooglePlay,但错误仍然存​​在。

所做的更改是无参数构造函数并更改了 WorkIem class to static

这是堆栈跟踪:

W 6758/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x401a15a0)
E 6758/AndroidRuntime: FATAL EXCEPTION: main
**Caused by: java.lang.RuntimeException: No-args constructor for class com.mypackage.model.UpdaterObject$UpdateReport does not exist. Register an InstanceCreator with Gson for this type to fix this problem.**
    at com.google.gson.MappedObjectConstructor.constructWithNoArgConstructor(MappedObjectConstructor.java:64)
    at com.google.gson.MappedObjectConstructor.construct(MappedObjectConstructor.java:53)
    at com.google.gson.JsonObjectDeserializationVisitor.constructTarget(JsonObjectDeserializationVisitor.java:40)
    at com.google.gson.JsonDeserializationVisitor.getTarget(JsonDeserializationVisitor.java:56)
    at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:109)
    at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:73)
    at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:51)
    at com.google.gson.Gson.fromJson(Gson.java:568)
    at com.google.gson.Gson.fromJson(Gson.java:515)
    at com.google.gson.Gson.fromJson(Gson.java:484)
    at com.google.gson.Gson.fromJson(Gson.java:434)
    at com.google.gson.Gson.fromJson(Gson.java:406)
    **at de.fliese.NewVersionCheckerActivity.onCreate(NewVersionCheckerActivity.java:35)**

这是第 35 行:

UpdateReport report = new Gson().fromJson(jsonStr, UpdateReport.class);

json-String 看起来像这样(Workitems 可以为空):

{"WorkItems":
[{"Url":"http://url1.comfoo.zip","TypeId":1,"LastModifiedServer":1352598239000},
{"Url":"http://url2.com/bar.zip","TypeId":4,"LastModifiedServer":1352598265000}],
 "ShowQuestionDialog":false,"IsOffline":false,"DoUpdate":true}

最后是我的带有 innerClass 的 UpdateReport 类:

public class UpdaterObject{     
public class UpdateReport {

            public boolean IsOffline;
            public boolean DoUpdate;
            public boolean ShowQuestionDialog;
            public List<WorkItem> WorkItems;

            public UpdateReport() {        }

            public UpdateReport(boolean isoffline, boolean doUpdate,
                    List<WorkItem> workitems) {
                IsOffline = isoffline;
                DoUpdate = doUpdate;
                WorkItems = workitems;
            }
        }

        public static class WorkItem {

            public int TypeId;
            public String Url;
            public long LastModifiedServer;

            public WorkItem() {        }

            public WorkItem(int typeId, String url, long lastModifiedServer) {
                TypeId = typeId;
                Url = url;
                LastModifiedServer = lastModifiedServer;
            }
        }
    //some methods [....]
    } //end class UpdaterObject

如果有人可以帮助我,我会很高兴。请确保并确保您的答案绝对正确,因为我无法测试它!那很好啊!

这是我在 StackOverFlow 上的第一篇文章。请公平。 :)

谢谢qd0r

【问题讨论】:

  • 关于TypeId的问题:你确定int type吗?
  • 我强烈建议覆盖 Exception 并在每个 Exception drop 上添加设备/制造商信息、Android 版本 ...。它将帮助您诊断问题。
  • 是的,TypeId 是 int。好主意!现在我创建了 3 个类:模型的 WorkItem 和 UpdateReport 以及返回 UpdateReport 对象的 getter 的(重命名的)UpdaterObject。现在所有类都有一个空的默认构造函数。希望能解决问题。
  • 有时您可以使用 null 参数获取 GSON 数据,并在 强制转换 到原始值时导致 JsonDeserializationContextDefault 问题。
  • 您使用的是过时的 Gson 版本。请升级到最新版本。

标签: android json exception gson


【解决方案1】:

来自Gson issue 255,HTC Desire HD 在其应用程序类路径中包含了一个过时的 Gson 副本。该问题有关于使用 jarjar 重新打包 Gson 版本以不与预安装版本冲突的说明。

【讨论】:

  • 哇!这个答案看起来真的很有帮助。现在我得到信息,我的应用程序在 HTC Desire HD 和 HTC Explorer 上存在问题。
  • 感谢@jesse wilson!问题已解决!这里的解决方案(code.google.com/p/google-gson/issues/detail?id=255):1)下载jarjar(code.google.com/p/jarjar/downloads/list)2)将jarjar-1.0.jar和gson-1.5.jar放在同一个文件夹中3)在这个文件夹中创建一个新的文本文件(rules.txt ) 4) 在文本文件中写入以下行: rule com.google.gson.** com.google.myjson.@1 5) 从命令行,使用命令“java -jar jarjar.jar process rules.txt”打开 jarjar gson-1.5.jar myjson-1.5.jar" 6) 将项目中的 gson 库替换为 myjson 并更新导入
  • 重要的附加说明:如果您使用 proguard,请不要忘记更改 gson-library 的规则。 ;)
  • +1 - 节省了大量时间。刚刚在 Play 中报道了这一点。我很想不执行此修复以使我的生活在未来变得更加复杂。放弃 Gingerbread IMO 的另一个原因。像HTC这样的人会不会再犯这种错误? Google 有没有指责过他们这样做有好处?
【解决方案2】:

就我而言,proguard 是问题所在。禁用 proguard 或将您的模型放入 proguard 规则文件中。为我工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    相关资源
    最近更新 更多