Как исправить NumberFormatException при использовании gson.fromJson - PullRequest
0 голосов
/ 04 января 2019

У меня есть архив, сохраненный в общих настройках пользовательских объектов (Book), и теперь, когда я обновил приложение (добавил новое свойство с именем Progress, которое является int), кажется, что gson пытается установить один из них. длинных в эту переменную int.

Это происходит только для избранных пользователей, которые загружают приложение через магазин, а я не смог его воспроизвести. Я вчера опубликовал что-то похожее, но без достаточной информации, и понял, что написал слишком рано.

Примечание. At 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, сеттеры и геттеры довольно нормальные, поэтому я их не включал.

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. Как я могу предотвратить это?

Он должен просто создать новый ArrayList of Book, но на самом деле он просто падает.

ДОБАВЛЕНИЕ:

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

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

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

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Как показывает ошибка, вы включили 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;
    }
}
0 голосов
/ 04 января 2019

Вы также можете использовать этот класс для своего класса книги:

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 в свой класс книги: import com.google.gson.annotations.Expose;import 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: Дата: Чт 03 Янв 17:13:47 EST 2019

Надеюсь, это поможет вам:)

0 голосов
/ 04 января 2019

Состояние исключения 1538513480946 слишком велико, чтобы вписаться в int, что является правильным.Это временная метка на 10/02/2018 @ 20:51 (UTC) и должна храниться как long.

Возможно, у вас есть более старая версия класса Book, где startTime или endTimeобъявляются как int, а не long (или, может быть, просто параметр установщика int).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...