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

时间:2013-11-13 08:46:01

标签: 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();
}

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

7 个答案:

答案 0 :(得分:27)

根据您的问题,您应该在将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.

这正是你在做什么

答案 1 :(得分:17)

这个“问题”记录在SharedPreferences.getStringSet()上。

getStringSet()返回SharedPreferences中存储的HashSet对象的引用。当您向此对象添加元素时,实际上会将它们添加到 inside 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

答案 2 :(得分:6)

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

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();
}

答案 3 :(得分:0)

在sharedpreferences中保存字符串

   SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this);
   editor.putString("text", mSaved.getText().toString());
   editor.commit();

从共享首选项中检索数据

 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
 String restoredText = prefs.getString("text", null);

答案 4 :(得分:0)

根据该文档,SharedPreferences中的字符串集应该被视为不可变的,当尝试修改它时,事情会向南移动。解决方法是: 获取现有集,复制它,更新副本,然后将其保存回共享首选项,就像它是一个新集。

Set<String> feedbackSet = getFeedbacksSet();
if(feedbackSet == null){
    feedbackSet = new HashSet<String>();
}

//make a copy of the set, update the copy and save the copy
Set<String> newFeedbackSet = new HashSet<String>();
JSONObject json = createJSONObjectfromFeedback(feedbackItem);
newFeedbackSet.add(json.toString());
newFeedbackSet.addAll(feedbackSet);
ed.putStringSet(CoreSetup.KEY_FEEDBACK, newFeedbackSet);
ed.commit();

答案 5 :(得分:0)

遇到同样的问题。通过在实例化之后和提交之前清除编辑器来解决它。

sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    sFavList = sPrefs.getStringSet(context.getResources().getString(R.string.pref_fav_key), null);
    sEditor = sPrefs.edit();
    sEditor.clear(); // added clear, now Set data persists as expected
    if (sFavList == null) sFavList = new HashSet<>();
    sFavList.add(title);
    sEditor.putStringSet(context.getResources().getString(R.string.pref_fav_key), sFavList).apply();

我尝试按其他人的建议制作副本,但这对我不起作用。

找到此解决方案here

答案 6 :(得分:0)

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, null);
    ed.commit();
    ed.putStringSet(CoreSetup.KEY_FEEDBACK, feedbackSet);
    ed.commit();
}