Android 从SharedReferences加载存储的json

Android 从SharedReferences加载存储的json,android,sharedpreferences,gson,Android,Sharedpreferences,Gson,问题 这个问题困扰了我很长时间。这种情况并不常见,但确实时常发生。问题如下: 我在SharedReferences中的s Gson序列化对象中保存了大量用户首选项。这边 当我需要这个对象时,我只调用一次存储器就将它加载到内存中。然而,出于某种奇怪的原因,我得到了这个错误: java.lang.RuntimeException: Unable to resume activity {com.a.b/com.a.b.SomeActivity}: java.lang.RuntimeException:

问题

这个问题困扰了我很长时间。这种情况并不常见,但确实时常发生。问题如下:

我在SharedReferences中的s Gson序列化对象中保存了大量用户首选项。这边 当我需要这个对象时,我只调用一次存储器就将它加载到内存中。然而,出于某种奇怪的原因,我得到了这个错误:

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}
可以观察到,json没有正确加载,它是一个无效的json,因此试图解析它只会抛出一个异常

一些其他事实

  • 抛出的每个异常都显示了完全相同的json解析问题。由于某些原因,这始终是正在加载的字符串:
rialFinished:false,“lastOpenedapid”:0,“appVersion”:35,“tutorialFinished”:false}

  • 这不是“设备特定问题”,至少我认为不是。证据:
    正如您所看到的,它不是特定于设备的。我还知道,它也不是特定于android版本的,我们已经从android
    2.3.6
    4.0.3
    4.1.1
    4.1.2
    4.0.4

  • 序列化的类是

    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;
    }
    
    }
    
  • 用于加载json的方法是:

        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);
                }
            }
    
可能的原因:

  • .这个问题说明一些Android设备不能很好地与SharedReferences配合使用。虽然我确信具体问题并非如此,但我不知道这是否与此有关

  • 这里可能有一些奇怪的过程安全问题

  • AppSettings是一个内部类。这会以某种方式影响Gson序列化吗


    • 您是否缺少双引号

      unable to parse type class com.a.b.storage.SomeClass$AppSettings with json: 
      
      rialFinished":false,"lastOpenedAppId":0,"appVersion":35,"tutorialFinished":false}
      
      如果是:

      unable to parse type class com.a.b.storage.SomeClass$AppSettings with json: 
      
      "rialFinished":false,"lastOpenedAppId":0,"appVersion":35,"tutorialFinished":false}
      

      我没有漏掉一个双引号,这正是问题所在。当Gson序列化AppSetting对象时,json字符串(应该是有效的json)被加载为无效的json。你看到问题了吗?对不起,我不同意。你在json中说的字符串根本不是你在这篇文章中所说的格式正确的json。