Android SharedPreferences String Set - some items are removed after app restart

前端 未结 6 1965
南笙
南笙 2021-02-03 19:38

I save a string set in the shared preferences, if I read it out it\'s ok. I start other activities, go back and read it again, it\'s ok. If I close the application, and start it

相关标签:
6条回答
  • 2021-02-03 20:18

    To save string in sharedprefernces

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

    To retrieve data from shared preference

     SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
     String restoredText = prefs.getString("text", null);
    
    0 讨论(0)
  • 2021-02-03 20:22

    This "problem" is documented on SharedPreferences.getStringSet().

    getStringSet() returns a reference of the stored HashSet object inside SharedPreferences. When you add elements to this object, they are added in fact inside SharedPreferences.

    The workaround is making a copy of the returned Set and putting the new Set into SharedPreferences. I tested it and it works.

    In Kotlin, that would be

        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
    
    0 讨论(0)
  • 2021-02-03 20:31

    According to the document, the String Set in SharedPreferences should treated as immutable, things go south when trying to modify it. A work around would be: Get the existing set, make a copy of it, update the copy and then save it back to the shared preferences like it was a new set.

    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();
    
    0 讨论(0)
  • 2021-02-03 20:35

    Ran into this same problem. Solved it by clearing the editor after instantiating and before committing.

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

    I tried creating a copy as others suggested, but that didn't work for me.

    Found this solution here.

    0 讨论(0)
  • 2021-02-03 20:38

    Try to create Copy of your set, and than you can save it in same prefs:

    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();
    }
    
    0 讨论(0)
  • 2021-02-03 20:42

    Based on your question, you should call commit only after 4 items have been added to the set. In your code, you are calling commit for each feedback which will overwrite the previous feedback.

    Update: 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.

    This is exactly what you are doing

    0 讨论(0)
提交回复
热议问题