Android: предпочтение набора строк не является постоянным

У меня проблема с сохранением предпочтений набора строк. У меня есть эти утилиты для хранения:

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

Я использую эти методы для обратной совместимости с GB. Но у меня есть проблема, что использование метода putStringSet не является постоянным для API > gingerbread. Он работает постоянно, пока приложение запускается. Но он исчезает после перезагрузки. Я опишу шаги:

  • Чистая установка приложения - нет предпочтения с ключом X
  • Я храню набор строк A с ключом X - предпочтение содержит A
  • Я храню набор строк B с ключом X - предпочтение содержит B
  • Закрыть приложение
  • Перезапуск приложения - предпочтение содержит A
  • Я храню набор строк C с ключом X - предпочтение содержит C
  • Закрыть приложение
  • Перезапуск приложения - предпочтение содержит A

Так что только первое значение является постоянным, и я не могу его перезаписать.

Другие примечания:

  • этот метод просто заменяет putStringSet и getStringSet. Поэтому я использую commit()... но в другом месте (см. Пример ниже).
  • Я попытался заменить commit() на apply() - без успеха
  • Когда я использую код для более старых API в новых API (я прокомментировал первые 4 строки в обоих методах), он работает безупречно, но он не настолько эффективен

Пример использования:

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

Ты очень поможешь.

Ответ 1

Это смехотворное количество дубликатов - я уверен, что вы делаете:

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

Короче говоря, андроид видит, что этот набор и один внутри относятся к одному и тому же набору и ничего не делают. Правильно?

Смотрите: Misbehavior при попытке сохранить набор строк с использованием SharedPreferences

Ответ 2

Мое состояние очень похоже на ваше, единственное различие заключается в перезапуске приложения, предпочтение содержит A, B, C, но при переустановке или перезагрузке телефона B & C исчез.

Я также попытался заменить commit() с помощью apply(), поскольку этот пост рекомендовал SharedPreferences не постоянно, но все равно не работать.

Я решил эту проблему, удалив и передав предпочтение перед его заменой:

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

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

Ps: вы можете набрать adb pull /data/data/<packagename>/shared_prefs/xxxx.xml в строке cmd, чтобы убедиться, что commit() действительно работает

Pps: Я думаю, что это ошибка с putStringSet....

надеюсь, что это поможет вам;)