Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set<String> in android sharedpreferences does not save on force close

Tags:

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();  } 
like image 209
Malin Avatar asked Jul 04 '13 11:07

Malin


People also ask

Can data in SharedPreferences persist after rebooting?

SharedPreferences is what Android and iOS apps use to store simple data in an allocated space. This data exists even when the app is shut down and starts up again; we can still retrieve the value as it was.

Is SharedPreferences thread safe?

The SharedPreferences implementation in Android is thread-safe but not process-safe. Normally your app will run all in the same process, but it's possible for you to configure it in the AndroidManifest. xml so, say, the service runs in a separate process than, say, the activity.

Are SharedPreferences persistent?

Android's built-in SharedPreferences storage mechanism allows us to store information that persists throughout the entire app. SharedPreferences allows you to create a file that stores primitive values as key-value pairs.


2 Answers

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)     } 
like image 159
Robbe Avatar answered Oct 05 '22 07:10

Robbe


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.

like image 27
g00dy Avatar answered Oct 05 '22 09:10

g00dy