I'm trying to store a set of strings using the SharedPreferences API.
Set<String> stringSet = sharedPrefs.getStringSet("key", new HashSet<String>());
stringSet.add(new_element);
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putStringSet(stringSet);
editor.commit()
The first time I execute the code above, stringSet
is set to the default value (the just created and empty HashSet
) and it is stored without problems.
The second and subsequent times I execute this code, a stringSet
object is returned with the first element added. I can add the element and, during the program execution, it is apparently stored in the SharedPreferences
. However, when the program is killed and the SharedPreferences
is loaded again from persistent storage, the newer values are lost.
How can the second and subsequent elements be stored so that they don't get lost?
This "problem" is documented on SharedPreferences.getStringSet
.
The SharedPreferences.getStringSet
returns a reference of the stored HashSet object
inside the SharedPreferences
. When you add elements to this object, they are added in fact inside the SharedPreferences
.
That is ok, but the problem comes when you try to store it: Android compares the modified HashSet that you are trying to save using SharedPreferences.Editor.putStringSet
with the current one stored on the SharedPreference
, and both are the same object!!!
A possible solution is to make a copy of the Set<String>
returned by the SharedPreferences
object:
Set<String> s = new HashSet<String>(sharedPrefs.getStringSet("key", new HashSet<String>()));
That makes s
a different object, and the strings added to s
will not be added to the set stored inside the SharedPreferences
.
Other workaround that will work is to use the same SharedPreferences.Editor
transaction to store another simpler preference (like an integer or boolean), the only thing you need is to force that the stored value are different on each transaction (for example, you could store the string set size).