23

Im trying to use androids sharedpreferences, I´ve logged everything and the code below really commits the string set. The problem is when I force close the app and start again, the settings.getStringSet returns an empty set. No errormessages anywhere.

I´ve tried PreferenceManager.getDefaultSharedPreferences but that does not work for me either.

Thanks for you time.

public static final String PREFS_NAME = "MyPrefsFile";
private static final String FOLLOWED_ROUTES = "followedRoutes";

and later on when saved is called:

public void onFollowClicked(View view){

SharedPreferences settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();

Set<String> follows =  settings.getStringSet(FOLLOWED_ROUTES, new HashSet<String>());
follows.add(routeId);

editor.putStringSet(FOLLOWED_ROUTES, follows);
editor.commit();

}
Malin
  • 655
  • 4
  • 10
  • 20
  • 1
    Do you respect the life cycle? In which state you save your data? – Steve Benett Jul 04 '13 at 11:59
  • everyting is saved before I force quit. the issue is that settings.getStringSet(... does not returns the values I commited to it. I´ve also tried replacing commit() to apply() - no success – Malin Jul 04 '13 at 12:01

2 Answers2

35

You can also work around the bug mentioned by g00dy this way:

Get the set from sharedPreferences and save it in a variable.

Then just delete the set in sharedpreferences before adding it again when saving.

SharedPreferences.Editor editor= sharedPref.edit();
editor.remove("mSet");
editor.apply(); 
editor.putStringSet("mSet", mSet);
editor.apply();

Make sure to use apply() or commit() twice.

Alternatively, if you are working in Kotlin simply :

PreferenceManager.getDefaultSharedPreferences(applicationContext)
    .edit {
        this.remove("mSet")
        this.apply()
        this.putStringSet("mSet", mSet)
    }
Richard Dapice
  • 838
  • 5
  • 10
Robbe
  • 2,610
  • 1
  • 20
  • 31
22

Take a look here.

Also for refference:

SharedPreferences

SharedPreferences.Editor

EDIT:

There's actually a bug with this one, see here. An extract from there:

This problem is still present on the 17 API level.

It is caused because the getStringSet() method of the SharedPreferences class doesn't return a copy of the Set object: it returns the entire object and, when you add new elements to it, the commitToMemory method of the SharedPrefencesImpl.EditorImpl class see that the existing value is equal to the previous one stored.

The ways to workaround this issue is to make a copy of the Set returned by SharedPreferences.getStringSet or force the write to memory using other preference that always change (for example, a property that stores the size of the set each time)

EDIT2:

There might be a solution here, take a look.

Community
  • 1
  • 1
g00dy
  • 6,752
  • 2
  • 30
  • 43
  • 1
    Cannot instantiate the type Set, since set is just an interface – Malin Jul 04 '13 at 12:23
  • Just a question, whats your minSDK in the `AndroidManifest`? – g00dy Jul 04 '13 at 12:24
  • it works fine if I use a string, but not a stringSet, and that is what I need. I´ve also tried: HashSet follows = (HashSet) settings.getStringSet(FOLLOWED_ROUTES, new HashSet()); – Malin Jul 04 '13 at 12:26
  • I edited my response. There's a bug with this usage and they have provided a workaround, or sort of .. – g00dy Jul 04 '13 at 12:27
  • 1
    The solution, as provided in your link [here](http://stackoverflow.com/questions/7361627/how-can-write-code-to-make-sharedpreferences-for-array-in-android) worked! As you said, this is a bug. getStringSet() method of the SharedPreferences does not return a copy of the Set object. Using JSONArray in combination with the getString() was how I solved the problem – Malin Jul 04 '13 at 13:29
  • Your answer is correct. I was trying to save Set in SharedPrefrences and it was not saving at all or saving after some time and NOT instantly - despite using `sharedPreferences.edit().putStringSet("favs", set).commit();` Instead of saving "set" I ended up saving `set = new HashSet<>(set);` which solved the problem – kosiara - Bartosz Kosarzycki Apr 07 '15 at 23:58
  • Make a copy of the Set that return and save the copy solve the problem!!! – Shlomi Fresko Jun 22 '16 at 09:08