The problem
This issue has been bugging me for quite some time. It is not very common, but it does happen from time to time. The problem is the following:
I save a bunch of user preferences in s Gson serialized object in SharedPreferences. This way, when I need the object I load it to memory doing only 1 call to storage. However, for some bizzare reason I am getting this error:
java.lang.RuntimeException: Unable to resume activity {com.a.b/com.a.b.SomeActivity}: java.lang.RuntimeException: unable to parse type class com.a.b.storage.SomeClass$AppSettings with json: rialFinished":false,"lastOpenedAppId":0,"appVersion":35,"tutorialFinished":false}
As can be observed, the json was not loaded properly, it is an invalid json, so trying to parse it just throws an exception.
Some Additional Facts
- Every single exception thrown shows the exact same json parsing issue. For some reason this is always the string that is being loaded:
rialFinished":false,"lastOpenedAppId":0,"appVersion":35,"tutorialFinished":false}
This is not a 'device specific issue' or at least I think so. Evidence:
As you can see, its not specific to a device. I also know for a fact that it is not specific to an android version either, we have this crashed logged from Android2.3.6
,4.0.3
,4.1.1
,4.1.2
,4.0.4
The class that is serialized is
class AppSettings { private boolean tutorialFinished; private boolean googleAuthTutorialFinished; private int appVersion; private int lastOpenedAppId; public AppSettings() { tutorialFinished = false; appVersion = NO_STORED_VERSION; googleAuthTutorialFinished = false; } public boolean isTutorialFinished() { return tutorialFinished; } public void setTutorialFinished(boolean tutorialFinished) { this.tutorialFinished = tutorialFinished; } public void setAppVerions(int appVerions) { this.appVersion = appVerions; } public void setGoogleAuthTutorialFinished(boolean googleAuthTutorialFinished) { this.googleAuthTutorialFinished = googleAuthTutorialFinished; } /** * * @return the stored app version or {@link AppSettingsStorage#NO_STORED_VERSION} if none was found */ public int getAppVerions() { return appVersion; } public boolean isGoogleAuthTutorialFinished() { return googleAuthTutorialFinished; } public int getLastOpenedAppId() { return lastOpenedAppId; } public void setLastOpenedAppId(int lastOpenedAppId) { this.lastOpenedAppId = lastOpenedAppId; } }
the method used to load the json is:
private T fromJson(String json) { try { return gson.fromJson(json, type); } catch (Exception e) { throw new RuntimeException("unable to parse type " + type + " with json: " + json); } }
Possible reasons:
https://code.google.com/p/android/issues/detail?id=14359. This issue states that some Android devices just don't work well with the SharedPreferences. Although I'm sure that specific issue is not the case here, I wonder if it has something to do.
Maybe there is some odd process-safety issue at hand here. (Shared Preferences And Thread/Process safety)
AppSettings is an inner class. Could this affect Gson serialization somehow?