【问题标题】:Gson IllegalStateException: Expected an int but was BEGIN_ARRAY at line 1 column YGson IllegalStateException:应为 int,但在第 1 行 Y 列是 BEGIN_ARRAY
【发布时间】:2022-09-16 21:36:39
【问题描述】:

由于我在 Schedule 类中添加了一个整数,因此 Gson 在某些设备上抛出错误:java.lang.IllegalStateException: Expected an int but was BEGIN_ARRAY at line 1 column Y(例如第 112 或 120 列等)。我查看了thisthis 的答案,这似乎表明Gson 期待一个int 但得到一个BEGIN_ARRAY char,但我有知道为什么在向类添加额外的 int 重构之后会发生这种情况。

在此之前,我从存储的 Json 字符串中解析 Schedule 对象列表的代码运行良好。由于抛出异常,我添加了Since annotation。这是 Schedule 类:

public class Schedule {

    /**
     * Added this variable 
     */
    @Since(1.1) private int addedVar;

    /**
     * All other variables have the @Since(1.0) annotation
     */
    @Since(1.0) all other vars;

}

解析时间表的函数:

public static ArrayList<Schedule> schedulesFromJson(String schedulesJson) {
    Type listType = new TypeToken<ArrayList<Schedule>>(){}.getType();
    Gson gson = new Gson();
    try {
        return gson.fromJson(schedulesJson, listType);
    } catch (Exception exception) {
        // Try to use the previous version of the schedule, because of IllegalStateException
        gson = new GsonBuilder().setVersion(1.0).create();
        return gson.fromJson(schedulesJson, listType);
    }
}

奇怪的是:在某些设备上(比如我自己的测试设备),这种崩溃从未发生过。由于崩溃,我添加了带有try和catch子句的Since注释,因为我预计它可能与添加的额外整数有关,并且可以通过简单地读取旧的Schedule版本来防止这种情况,但这仍然会抛出catch 子句中的相同异常。

为什么会发生这种情况有任何帮助吗?

【问题讨论】:

  • 您使用的是 ProGuard 还是 R8,并且您是否已将其配置为不混淆您的模型类?
  • 让我试试看,我确实配置了 ProGuard。您知道为什么这种情况可能只发生在某些设备上而不是全部设备上吗?
  • 不,我误读了您的问题,并认为它可能只发生在您的测试设备上,因为它没有运行发布版本(因此代码可能没有被混淆)。否则我真的不知道为什么它只会影响某些设备。如果您的代码生成的 JSON(或 Gson 异常消息 at line X column Y path &lt;path&gt; 中的路径)包含随机字母作为 JSON 成员名称,则很可能您的 ProGuard 配置不正确。

标签: gson storage


【解决方案1】:

想通了:因为 Proguard 没有设置为不是混淆 Schedule 对象(感谢@Marcono1234 让我朝正确的方向倾斜),Schedule 对象作为混淆对象({"a":true,"b":"Name","c":[true,true,true,true,true,false,false], etc})存储在存储中,而不是使用变量名。

抛出异常的原因是,基于添加addedVar 之前的Schedule 类结构,调度中有一个数组。举个例子更容易。

旧的时间表类:

public class Schedule {
    private boolean isActive;
    private String scheduleName;
    private boolean[] days;
    private final long timeCreated;
    private ArrayList<String> list;
}

新的时间表类:

public class Schedule {
    private boolean isActive;
    private String scheduleName;
    private boolean[] days;
    private final long timeCreated;
    private int addedVar; // <-- Here it goes wrong
    private ArrayList<String> list;
}

由于在 ArrayList&lt;String&gt; list 之前添加了 int 变量,当 Gson 尝试反序列化存储的 JSON 字符串时,它希望看到一个 int(addedVar,但从列表中看到了 BEGIN_ARRAY。

我通过在我的 Schedule 类中的列表之后放置 ` addedVar ` 来修复它,因此Since(1.0) 注释将正常工作。

【讨论】:

    猜你喜欢
    • 2016-07-12
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多