Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: String set preference is not persistent

I have a problem with storing string set preference. I have these utility methods for storing:

public static void putStringSet(SharedPreferences pref, Editor e, String key, Set<String> set)
{
    if (Utils.isApiLevelGreaterThanGingerbread())
    {
        // e.remove(key); // I tried to remove it here
        e.putStringSet(key, set);
    }
    else
    {
        // removes old occurences of key
        for (String k : pref.getAll().keySet())
        {
            if (k.startsWith(key))
            {
                e.remove(k);
            }
        }

        int i = 0;
        for (String value : set)
        {
            e.putString(key + i++, value);
        }
    }
}

public static Set<String> getStringSet(SharedPreferences pref, String key, Set<String> defaultValue)
{
    if (Utils.isApiLevelGreaterThanGingerbread())
    {
        return pref.getStringSet(key, defaultValue);
    }
    else
    {
        Set<String> set = new HashSet<String>();

        int i = 0;

        Set<String> keySet = pref.getAll().keySet();
        while (keySet.contains(key + i))
        {
            set.add(pref.getString(key + i, ""));
            i++;
        }

        if (set.isEmpty())
        {
            return defaultValue;
        }
        else
        {
            return set;
        }
    }
}

I use these methods to be backward compatible with GB. But I have a problem that using putStringSet method isn't persistent for API > gingerbread. It is persistent while app is runing. But it dissapears after restart. I will describe the steps:

  1. Clean install of application - there is no preference with key X
  2. I store string set A with key X - preference contains A
  3. I store string set B with key X - preference contains B
  4. Close app
  5. Restart of app - preference contains A
  6. I store string set C with key X - preference contains C
  7. Close app
  8. Restart of app - preference contains A

So only the first value is persistent and I cannot overwrite it.

Other notes:

  1. this methods just replaces putStringSet and getStringSet. So I use commit()...but elsewhere (see example below).
  2. I tried to replace commit() with apply() - no success
  3. When I use code for older APIs in newer APIs (I commented first 4 lines in both methods) it works flawlessly but it isn't so efficient

Example of use:

Editor e = mPref.edit();
PreferencesUtils.putStringSet(mPref, e, GlobalPreferences.INCLUDED_DIRECTORIES, dirs);
e.commit();

Thnak you very much for help.

like image 616
Bhiefer Avatar asked May 29 '13 17:05

Bhiefer


People also ask

Is SharedPreferences persistent?

Terminology. Shared preferences: An Android class that allows apps to store key-value pairs of primitive data types. Once saved, information in shared preferences will persist across sessions.

Where are Android preferences stored?

Android stores Shared Preferences settings as XML file in shared_prefs folder under DATA/data/{application package} directory. The DATA folder can be obtained by calling Environment. getDataDirectory() .

How does Android shared preferences work?

A SharedPreferences object points to a file containing key-value pairs and provides simple methods to read and write them. Each SharedPreferences file is managed by the framework and can be private or shared. This page shows you how to use the SharedPreferences APIs to store and retrieve simple values.

What are shared preferences java?

Shared Preferences is the way in which one can store and retrieve small amounts of primitive data as key/value pairs to a file on the device storage such as String, int, float, Boolean that make up your preferences in an XML file inside the app on the device storage.


2 Answers

This has a ridiculous amount of duplicates - I bet that you do :

set = prefs.getStringSet("X", new HashSet<String>());
set.add("yada yada");
prefs.putStringSet("X", set);

In short android sees that set and the one inside refer to the same set and does nothing. Correct ?

See: Misbehavior when trying to store a string set using SharedPreferences

like image 149
Mr_and_Mrs_D Avatar answered Oct 18 '22 09:10

Mr_and_Mrs_D


My condition is very similar to yours, the only difference is when restart the app, preference contains A, B, C, but when reinstall it or reboot the phone, B&C are gone.

I also tried replace commit() with apply(), as this post adviced SharedPreferences not persistent , but still not to work.

I solved this problem by remove & commit the preference before replacing it:

editor.remove("StringSetKey");
editor.commit();

editor.putStringSet("StringSetKey", newSet);
editor.commit();

Ps: you can type adb pull /data/data/<packagename>/shared_prefs/xxxx.xml in cmd line to see if the commit() really works

Pps: I think this is a bug with putStringSet....

hope this will help you ;)

like image 1
zhangxaochen Avatar answered Oct 18 '22 11:10

zhangxaochen