Android SharedPreferences String Set - 应用程序重启后删除了一些项目

use*_*423 33 android sharedpreferences

我在共享首选项中保存了一个字符串集,如果我把它读出来就可以了.我开始其他活动,回去再读一遍,没关系.如果我关闭应用程序,然后重新启动它,我会得到设置,但只有1项而不是4.它会一直发生.有一个已知的问题吗?我该怎么办?

在类中,在应用程序的oncreate方法中创建的内容我有一个SharedPreferences和一个SharePreferences.Editor变量.我在保存和加载方法中使用它们.

public void saveFeedback(FeedbackItem feedbackItem) {
    checkSp();
    Set<String> feedbackSet = getFeedbacksSet();
    if(feedbackSet == null){
        feedbackSet = new HashSet<String>();
    }
    JSONObject json = createJSONObjectfromFeedback(feedbackItem);
    feedbackSet.add(json.toString());
    ed.putStringSet(CoreSetup.KEY_FEEDBACK, feedbackSet);
    ed.commit();
}

public Set<String> getFeedbacksSet(){
    checkSp();
    Set<String> ret = sp.getStringSet(CoreSetup.KEY_FEEDBACK, null);
    return ret;
}

private void checkSp(){
    if(this.sp == null)
        this.sp = applicationContext.getSharedPreferences(applicationContext.getPackageName(), Context.MODE_PRIVATE);
    if(this.ed == null)
        this.ed = this.sp.edit();
}
Run Code Online (Sandbox Code Playgroud)

我只是无法理解怎么可能发生,在应用程序运行时完美存储所有项目,然后在重新启动后并非所有项目都在集合中.而且我认为如果所有物品都被移除,它可能比一些物品消失更可接受,而且还有一件物品.有解释吗?

Mad*_*uja 28

根据您的问题,您应该在将4个项目添加到集合后调用commit.在您的代码中,您为每个反馈调用commit,这将覆盖先前的反馈.

更新:http: //developer.android.com/reference/android/content/SharedPreferences.html#getStringSet(java.lang.String ,java.util.Set)

Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.

这正是你在做的事情

  • 谢谢你的意思!像这样包装解决了这个问题:new HashSet <>(mPrefs.getStringSet(KEY,new HashSet <String>())); (11认同)

Jad*_* Gu 17

这个"问题"记录在案 SharedPreferences.getStringSet().

getStringSet()返回SharedPreferences中存储的HashSet对象的引用.向此对象添加元素时,它们实际上会添加 SharedPreferences中.

解决方法是复制返回的Set并将新Set放入SharedPreferences.我测试了它,它的工作原理.

在Kotlin,那就是

    val setFromSharedPreferences = sharedPreferences.getStringSet("key", mutableSetOf())
    val copyOfSet = setFromSharedPreferences.toMutableSet()
    copyOfSet.add(addedString)

    val editor = sharedPreferences.edit()
    editor.putStringSet("key", copyOfSet)
    editor.apply() // or commit() if really needed
Run Code Online (Sandbox Code Playgroud)


小智 7

尝试创建集合的副本,然后将其保存在相同的首选项中:

private Set<String> _setFromPrefs;


public void GetSetFromPrefs()
{
    SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
    Set<String> someSets = sharedPref.getStringSet("some_sets", new HashSet<String>() );
    _setFromPrefs = new HashSet<>(someSets); // THIS LINE CREATE A COPY
}


public void SaveSetsInPrefs()
{
    SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putStringSet("some_sets", _setFromPrefs);
    editor.commit();
}
Run Code Online (Sandbox Code Playgroud)