Since I've added an integer to my Schedule class, Gson is throwing an error on some devices: java.lang.IllegalStateException: Expected an int but was BEGIN_ARRAY at line 1 column Y
(e.g. column 112 or 120 etc). I looked at this and this answer, which seems to suggest Gson is expecting an int but is getting a BEGIN_ARRAY char, but I have no idea why this would happen after the refactor of adding an extra int to the class.
Before this, my code to parse the list of Schedule objects from a stored Json string was working perfectly fine. I added the Since annotation because of the exception being thrown. Here's the Schedule class:
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;
}
The function to parse the schedules:
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);
}
}
The strange thing is: on some devices (like my own test devices), this crash never happened. Because of the crash, I added the Since annotation with the try and catch clause, since I expected it might have to do with the extra integer being added and could prevent that by simply reading in the old Schedule version, but this is still throwing the same exception in the catch clause.
Any help with why this is happening?
Figured it out: Because Proguard wasn't set up to not obfuscate the Schedule object (thanks @Marcono1234 for tipping me in the right direction), the Schedule object was stored in storage as an obfuscated object ({"a":true,"b":"Name","c":[true,true,true,true,true,false,false], etc}
) instead of using the variable names.
The Exception was thrown because, based on the Schedule class structure before adding the addedVar
, there was an array in the schedule. Easier with example.
The old schedule class:
public class Schedule {
private boolean isActive;
private String scheduleName;
private boolean[] days;
private final long timeCreated;
private ArrayList<String> list;
}
The new schedule class:
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;
}
Because of adding the int variable before the ArrayList<String> list
, when Gson tried to deserialize the stored JSON String, it expected to see an int (the addedVar
, but instead saw BEGIN_ARRAY, from the list.
I fixed it by placing the `addedVar`` after the list in my Schedule class, so the Since(1.0) annotation will properly work.