使用gson.fromJson

时间:2019-01-04 11:49:41

标签: java android json gson

我有一个保存在共享首选项中的数组列表,其中包含自定义对象(Book),现在我已经更新了应用程序(添加了一个名为Progress的新属性,它是一个int),看来gson正在尝试放置一个多于这个int变量。

这仅适用于部分用户,这些用户通过商店下载了该应用,而我却无法复制该应用。我昨天在这里发布了类似的内容,但没有足够的信息,并且意识到我发布得太早了。

注意:在myrr.auto1.myreadingrecord1.sharedFunctions.loadArrayList(sharedFunctions.java:40)     bookList = gson.fromJson(json,type); 线

static ArrayList<Book> loadArrayList(Context context) {
    ArrayList<Book> bookList;
    SharedPreferences mPrefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
    Gson gson = new Gson();
    String json = mPrefs.getString("finishedBooks", "");
    if (json.isEmpty()) {
        bookList = new ArrayList<>();
    } else {
        Type type = new TypeToken<ArrayList<Book>>() {
        }.getType();
        bookList = gson.fromJson(json, type);
    }
    return bookList;
}


Fatal Exception: com.google.a.r: java.lang.NumberFormatException: Expected an int but was 1538513480946 at line 1 column 1891 path $[0].i
   at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:227)
   at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:217)
   at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
   at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
   at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
   at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
   at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
   at com.google.gson.Gson.fromJson(Gson.java:888)
   at com.google.gson.Gson.fromJson(Gson.java:853)
   at com.google.gson.Gson.fromJson(Gson.java:802)
   at myrr.auto1.myreadingrecord1.sharedFunctions.loadArrayList(sharedFunctions.java:40)

这是旧版本中json字符串的样子:

{"author":"Kerry Cohen Hoffmann",
"categories":"Juvenile Fiction",
"description":"Feeling neglected by her divorced parents and distant         older sister, fourteen-year-old Jessica discovers how easily she is able to         attract the attention of men and boys, without realizing the risks of her     behavior.",
"endTime":1546742469961,
"imageURL":"http://books.google.com/books/content?id\u003d7wLjQH5_HjEC\u0026printsec\u003dfrontcover\u0026img\u003d1\u0026zoom\u003d5\u0026edge\u003dcurl\u0026source\u003dgbs_api",
"language":"en",
"moreInfoLink":"http://books.google.com/books?id\u003d7wLjQH5_HjEC\u0026dq\u003deasy\u0026hl\u003d\u0026as_pt\u003dBOOKS\u0026source\u003dgbs_api",
"pages":"176",
"startTime":1546553627662,
"title":"Easy"}

这是Book类的属性,setter和getter很正常,所以我没有包括它们。

public class Book implements Serializable{
private String author;
private String title;
private String pages;
private String imageURL;
private String description;
private String categories;
private String moreInfoLink;
private String language;
private int progress = 0;
private long startTime = 0L;
private long endTime = 0L;

public Book (String author, String title, String pages, String description, String imageURL, String categories, String moreInfoLink, String language) {
    this.author = author;
    this.title = title;
    this.pages = pages;
    this.description = description;
    this.imageURL = imageURL;
    this.categories = categories;
    this.moreInfoLink = moreInfoLink;
    this.language = language;
}

因此,对于某些用户,fromJson会选择用户,将starttime或endtime值放入新的progress属性中。我该如何预防?

它应该只创建一个新的Book ArrayList,但是实际上它只是崩溃了。

添加:

public void setEndTime(long endTime) {
    this.endTime = endTime;
}

public void setStartTime(long startTime) {
    this.startTime = startTime;}

theCRBook.setStartTime(Calendar.getInstance().getTimeInMillis());

3 个答案:

答案 0 :(得分:2)

如错误所示,您在minifyEnabled中启用了build.gradle以使代码模糊。在这种情况下,您需要对模型中的每个变量进行@SerializedName("endTime")@SerializedName("startTime") ...等操作,因为该变量的名称将在发行版中更改。

public class Book implements Serializable {

    @SerializedName("author")
    private String author;

    @SerializedName("title")
    private String title;

    @SerializedName("pages")
    private String pages;

    @SerializedName("imageURL")
    private String imageURL;

    @SerializedName("description")
    private String description;

    @SerializedName("categories")
    private String categories;

    @SerializedName("moreInfoLink")
    private String moreInfoLink;

    @SerializedName("language")
    private String language;

    @SerializedName("progress")
    private int progress = 0;

    @SerializedName("startTime")
    private long startTime = 0L;

    @SerializedName("endTime")
    private long endTime = 0L;

    public Book (String author, String title, String pages, String description, String imageURL, String categories, String moreInfoLink, String language) {
        this.author = author;
        this.title = title;
        this.pages = pages;
        this.description = description;
        this.imageURL = imageURL;
        this.categories = categories;
        this.moreInfoLink = moreInfoLink;
        this.language = language;
    }
}

答案 1 :(得分:1)

异常状态1538513480946太大,无法放入int,这是正确的。这是时间戳记,时间为10/02/2018 @ 8:51 pm(UTC),应存储为long

也许您使用的是Book类的旧版本,其中startTimeendTime被声明为int而不是long(或者可能只是setter参数)是int)。

答案 2 :(得分:1)

您也可以将此类用于您的图书班:

public class Book {
    @SerializedName("author")
    @Expose
    private String author;
    @SerializedName("categories")
    @Expose
    private String categories;
    @SerializedName("description")
    @Expose
    private String description;
    @SerializedName("endTime")
    @Expose
    private long endTime;
    @SerializedName("imageURL")
    @Expose
    private String imageURL;
    @SerializedName("language")
    @Expose
    private String language;
    @SerializedName("moreInfoLink")
    @Expose
    private String moreInfoLink;
    @SerializedName("pages")
    @Expose
    private String pages;
    @SerializedName("startTime")
    @Expose
    private long startTime;
    @SerializedName("title")
    @Expose
    private String title;

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getCategories() {
        return categories;
    }

    public void setCategories(String categories) {
        this.categories = categories;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public long getEndTime() {
        return endTime;
    }

    public void setEndTime(long endTime) {
        this.endTime = endTime;
    }

    public String getImageURL() {
        return imageURL;
    }

    public void setImageURL(String imageURL) {
        this.imageURL = imageURL;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    public String getMoreInfoLink() {
        return moreInfoLink;
    }

    public void setMoreInfoLink(String moreInfoLink) {
        this.moreInfoLink = moreInfoLink;
    }

    public String getPages() {
        return pages;
    }

    public void setPages(String pages) {
        this.pages = pages;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

只需在您的图书课中导入gson: 导入com.google.gson.annotations.Expose; 导入com.google.gson.annotations.SerializedName;

之后,您可以轻松地从书本中获取一些开始/结束时间,并将其转换为日期,如下所示:

ArrayList<Book> books = loadArrayList(this);
Date date = new Date(books.get(0).getStartTime());
Log.i(TAG, "Date: " + date.toString());

您将从json字符串中获取日期: 日期:2019年1月3日星期四17:13:47

希望这可以为您提供帮助:)