google / gson

A Java serialization/deserialization library to convert Java Objects into JSON and back
Apache License 2.0
23.35k stars 4.28k forks source link

com.google.gson.jsonsyntaxexception java.lang.illegalstateexception expected an int but was boolean #1730

Closed mrudulamrudu closed 4 years ago

mrudulamrudu commented 4 years ago

In my app I have search functionality, when ever user searches for something I make a network call fetch suggestions. When user clicks on any of the suggestion I am storing that POJO into shared preferences using Gson and when the screen loads fist I am fetching the stored data from the preferences and deserializing using Gson. It all worked fine but recently I have added ProductTier object to the search item, it never crashed during testing. But it started crashing after the release. I understood that the gson is throwing error while deserializing but I can't think of any scenario where I am passing an int instead of boolean.

public class SearchItem implements Parcelable {

private static final int ITEM_KEY_WORD = 0;
private static final int ITEM_PRODUCT = 1;

@SerializedName("name")
private String name;

@SerializedName("itemKeyword")
private String itemKeyWord;

@SerializedName("productId")
private String productId;

@SerializedName("productTier")
private ProductTier productTier;

private int itemType;
private boolean isHeader = false;
private boolean isPopular = false;

public SearchItem(String name, String productId){
    this.name = name;
    this.productId = productId;
}

public SearchItem(String name, String itemKeyWord, String productId, int itemType,
                  boolean isHeader, boolean isPopular) {
    this.name = name;
    this.itemKeyWord = itemKeyWord;
    this.productId = productId;
    this.itemType = itemType;
    this.isHeader = isHeader;
    this.isPopular = isPopular;
}

private SearchItem(Parcel in) {
    this.name = in.readString();
    this.itemKeyWord = in.readString();
    this.productId = in.readString();
    itemType = TextUtils.isEmpty(itemKeyWord) ? ITEM_PRODUCT : ITEM_KEY_WORD;
    productTier = in.readParcelable(ProductTier.class.getClassLoader());
}

public static final Creator<SearchItem> CREATOR = new Creator<SearchItem>() {
    @Override
    public SearchItem createFromParcel(Parcel in) {
        return new SearchItem(in);
    }

    @Override
    public SearchItem[] newArray(int size) {
        return new SearchItem[size];
    }
};

public String getItemKeyWord() {
    return itemKeyWord;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getProductId() {
    return productId;
}

public int getItemType() {
    return itemType;
}

public void setItemType(int itemType) {
    this.itemType = itemType;
}

public boolean isHeader() {
    return isHeader;
}

public void setHeader(boolean header) {
    isHeader = header;
}

public boolean isPopular() {
    return isPopular;
}

public void setPopular(boolean popular) {
    isPopular = popular;
}

public ProductTier getProductTier() {
    return productTier;
}

@Override
public int describeContents() {
    return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(name);
    dest.writeString(itemKeyWord);
    dest.writeString(productId);
    dest.writeParcelable(productTier, flags);
}

@Override
public boolean equals(@Nullable Object obj) {
    SearchItem that = (SearchItem) obj;
    if (that == null) return false;
    return this.name.equals(that.name);
}
}

//

public class ProductTier implements Parcelable {

@SerializedName("categoryId")
private String categoryId;

@SerializedName("liquorTypeId")
private String liquorTypeId;

@SerializedName("subCategoryId")
private String subCategoryId;

protected ProductTier(Parcel in) {
    categoryId = in.readString();
    liquorTypeId = in.readString();
    subCategoryId = in.readString();
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(categoryId);
    dest.writeString(liquorTypeId);
    dest.writeString(subCategoryId);
}

@Override
public int describeContents() {
    return 0;
}

public static final Creator<ProductTier> CREATOR = new Creator<ProductTier>() {
    @Override
    public ProductTier createFromParcel(Parcel in) {
        return new ProductTier(in);
    }

    @Override
    public ProductTier[] newArray(int size) {
        return new ProductTier[size];
    }
};

public String getCategoryId() {
    return categoryId;
}

public String getLiquorTypeId() {
    return liquorTypeId;
}

public String getSubCategoryId() {
    return subCategoryId;
}
}

class Utils {

  public static ArrayList<SearchItem> getRecentSearches(Context context) {
        ArrayList<SearchItem> searchItems = new ArrayList<>();
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        String list = preferences.getString(Constants.RECENT_SEARCHES, "");
        try {
            JSONArray jsonArray = new JSONArray(list);
            if (jsonArray.length() > 0) {
                Gson gsonVal = new Gson();
                int i = 0;
                while (i < jsonArray.length()) {
                    searchItems.add(gsonVal.fromJson(jsonArray.getJSONObject(i).toString(), SearchItem.class));
                    i++;
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return searchItems;
    }

 public static void storeSearchItemToRecentSearches(Context context, SearchItem searchItem) {
        if (searchItem == null) return;
        searchItem.setPopular(false);
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();
        String list = preferences.getString(Constants.RECENT_SEARCHES, "");
        ArrayList<SearchItem> previousResults = new ArrayList<>();
        try {
            JSONArray jsonArray = new JSONArray(list);
            if (jsonArray.length() > 0) {
                Gson gsonVal = new Gson();
                int i = 0;
                while (i < jsonArray.length()) {
                    previousResults.add(gsonVal.fromJson(jsonArray.getJSONObject(i).toString(), SearchItem.class));
                    i++;
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

  if (previousResults.size() == 5) {
            previousResults.remove(previousResults.size() - 1);
            previousResults.add(0, searchItem);
        }else {
            previousResults.add(0, searchItem);
        }
        Gson gson = new Gson();
        String val = gson.toJson(previousResults);
        editor.putString(Constants.RECENT_SEARCHES, val);
        editor.apply();
    }
}

the crash is at this line searchItems.add(gsonVal.fromJson(jsonArray.getJSONObject(i).toString(), SearchItem.class)); in the getRecentSearches method.

sachinsingh15 commented 2 years ago

@mrudulamrudu Can you please explain? What was the issue? I am also facing the same issue.