Удаление элементов из набора строк в общих предпочтениях, не сохраняющихся в перезагрузках приложений [duplicate]

size = 3
matrix_surprise = [[0] * size] * size
matrix = [[0]*size for i in range(size)]

Frames and Objects [/g1]

Live Python Tutor Визуализировать

56
задан joojaa 29 May 2014 в 09:17
поделиться

4 ответа

Эта «проблема» документирована на SharedPreferences.getStringSet .

SharedPreferences.getStringSet возвращает ссылку на сохраненный объект HashSet внутри SharedPreferences. Когда вы добавляете элементы к этому объекту, они фактически добавляются внутри SharedPreferences.

Это нормально, но проблема возникает, когда вы пытаетесь его сохранить: Android сравнивает модифицированный HashSet, который вы пытаетесь для сохранения с помощью SharedPreferences.Editor.putStringSet с текущим, сохраненным на SharedPreference, и оба являются одним и тем же объектом !!!

Возможное решение состоит в том, чтобы сделать копию Set<String>, возвращенную SharedPreferences:

Set<String> s = new HashSet<String>(sharedPrefs.getStringSet("key", new HashSet<String>()));

Это делает s другим объектом, а строки, добавленные в s, не будут добавлены в набор, сохраненный внутри SharedPreferences.

Другим обходным решением, которое будет работать, является использование одной и той же транзакции SharedPreferences.Editor для хранения другого более простого предпочтения (например, целочисленного или логического), единственное, что вам нужно, это заставить, чтобы хранимое значение отличалось для каждой транзакции (например, вы можете сохранить размер набора строк).

128
ответ дан Michał Tajchert 20 August 2018 в 19:35
поделиться
  • 1
    Я уже +1, но не могли бы вы предоставить ссылку на источник, подтверждающий ваше утверждение: «Android сравнивает измененный HashSet, который вы пытаетесь сохранить, используя SharedPreferences.Editor.putStringSet с текущим, хранящимся в SharedPreference & quot; – Mr_and_Mrs_D 24 December 2013 в 19:54
  • 2
    Я весь день бил головой о стену! Благодаря!!! – Tim 22 January 2016 в 03:03
  • 3
    Второй вариант (сохранить счетчик) работал отлично для меня. Благодаря! – MarionaDSR 24 March 2017 в 20:56
  • 4
    Отработал 9 часов, глядя на мой код на этом. Благодаря тонну. – AnupamChugh 27 July 2018 в 19:39

Это поведение задокументировано так:

from getStringSet:

"Обратите внимание, что вы не должны изменять экземпляр набора, возвращенный этим вызовом. сохраненных данных не гарантируется, если вы это сделаете, и ваша способность вообще не изменять этот экземпляр. "

И это кажется вполне разумным, особенно если оно задокументировано в API, иначе это API должен будет копировать каждый доступ. Поэтому причиной этого дизайна была, пожалуй, производительность. Я полагаю, что они должны заставить эту функцию возвращать результат, завернутый в немодифицируемый экземпляр класса, но это снова требует выделения.

12
ответ дан Dale 20 August 2018 в 19:35
поделиться
  • 1
    Сегодня вечером я отредактировал свой собственный ответ. Я понял, что это правильно документировано, но когда вы много раз пишете код, вы не смотрите на документацию в таких вещах. Это единственная причина, чтобы сохранить этот запрос + ответ, ИМХО, потому что это класс полезности, и такое объяснение может помочь кому угодно. Спасибо за разъяснение – JoseLSegura 26 December 2012 в 11:05

Ищет решение для одной и той же проблемы, разрешил его:

1) Извлеките существующий набор из общих настроек

2) Сделайте копию

3) Обновить копию

4) Сохранить копию

SharedPreferences.Editor editor = sharedPrefs.edit();
Set<String> oldSet = sharedPrefs.getStringSet("key", new HashSet<String>());

//make a copy, update it and save it
Set<String> newStrSet = new HashSet<String>();    
newStrSet.add(new_element);
newStrSet.addAll(oldSet);

editor.putStringSet("key",newStrSet); edit.commit();

Почему

3
ответ дан s-hunter 20 August 2018 в 19:35
поделиться

Я пробовал все вышеперечисленные ответы, никто не работал для меня. Поэтому перед добавлением нового элемента в список старого общего pref, я сделал следующие шаги

  1. , сделайте его копию
  2. вызовите метод с указанной копией в качестве параметра к этому методу.
  3. внутри этого метода очистить общий префикс, который удерживает эти значения.
  4. добавить значения, присутствующие в копии, в очищенное разделяемое предпочтение, оно будет рассматривать его как новое.
    public static void addCalcsToSharedPrefSet(Context ctx,Set<String> favoriteCalcList) {
    
    ctx.getSharedPreferences(FAV_PREFERENCES, 0).edit().clear().commit();
    
    SharedPreferences sharedpreferences = ctx.getSharedPreferences(FAV_PREFERENCES, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedpreferences.edit();
    editor.putStringSet(FAV_CALC_NAME, favoriteCalcList);
    editor.apply(); }
    

Я столкнулся с проблемой, когда значения не были постоянными, если я снова открываю приложение после очистки приложения из фона, был показан только первый элемент, добавленный в список.

0
ответ дан Swapnil 20 August 2018 в 19:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: