Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 again, I get the set, but with only 1 item instead of 4. It happens all the time. Is there a known issue? What could I do wrong?

In a class, what is created in the application's oncreate method I have a SharedPreferences and a SharePreferences.Editor variable. I use them in the save and load methods.

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

I just can't understand how could it happen, to store perfectly all items while the app is running, then after a restart not all items are in the set. And I think if all items are removed it could be more acceptable than some items are gone, and one item is still there. Is there an explanation?

like image 992
user2313423 Avatar asked Nov 13 '13 08:11

user2313423


People also ask

Does SharedPreferences persist after uninstall?

SharedPreferences is application specific, i.e. the data is lost on performing one of the following options: on uninstalling the application.

What does the SharedPreferences editor Clear () method do?

To clear all the values in the shared preferences file, call the clear() method on the shared preferences editor and apply the changes. SharedPreferences.

What is mode in SharedPreferences?

In simple terms: MODE_PRIVATE is the operating mode for the preferences. It is the default mode and means the created file will be accessed by only the calling application. In MODE_WORLD_READABLE other application can read the created file but can not modify it.

Why do we use SharedPreferences in Android?

If you have a relatively small collection of key-values that you'd like to save, you should use the SharedPreferences APIs. A SharedPreferences object points to a file containing key-value pairs and provides simple methods to read and write them.


2 Answers

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

like image 59
Madhur Ahuja Avatar answered Sep 19 '22 20:09

Madhur Ahuja


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 
like image 39
Jaden Gu Avatar answered Sep 17 '22 20:09

Jaden Gu