Android SharedPreferences String Set – некоторые элементы удаляются после перезагрузки приложения

Я сохраняю набор строк в общих настройках, если я его прочитаю, все в порядке. Я начинаю другие действия, возвращаюсь и читаю его снова, все в порядке. Если я закрою приложение и запустил его снова, я получаю набор, но только с одним элементом вместо 4. Это происходит все время. Есть ли известная проблема? Что я могу сделать неправильно?

В классе, что создается в методе oncreate приложения, у меня есть SharedPreferences и переменная SharePreferences.Editor. Я использую их в методах сохранения и загрузки.

public void saveFeedback(FeedbackItem feedbackItem) { checkSp(); Set<String> feedbackSet = getFeedbacksSet(); if(feedbackSet == null){ feedbackSet = new HashSet<String>(); } JSONObject json = createJSONObjectfromFeedback(feedbackItem); feedbackSet.add(json.toString()); ed.putStringSet(CoreSetup.KEY_FEEDBACK, feedbackSet); ed.commit(); } public Set<String> getFeedbacksSet(){ checkSp(); Set<String> ret = sp.getStringSet(CoreSetup.KEY_FEEDBACK, null); return ret; } private void checkSp(){ if(this.sp == null) this.sp = applicationContext.getSharedPreferences(applicationContext.getPackageName(), Context.MODE_PRIVATE); if(this.ed == null) this.ed = this.sp.edit(); } 

Я просто не понимаю, как это могло случиться, чтобы хранить все элементы во время работы приложения, а затем после перезагрузки не все элементы находятся в наборе. И я думаю, что если все элементы будут удалены, это может быть более приемлемым, чем некоторые предметы, и один элемент все еще существует. Есть ли объяснение?

Solutions Collecting From Web of "Android SharedPreferences String Set – некоторые элементы удаляются после перезагрузки приложения"

Исходя из вашего вопроса, вы должны вызывать фиксацию только после того, как в набор добавлено 4 элемента. В вашем коде вы вызываете фиксацию для каждой обратной связи, которая перезапишет предыдущую обратную связь.

Обновление : http://developer.android.com/reference/android/content/SharedPreferences.html#getStringSet(java.lang.String , java.util.Set)

Note that you must not modify the set instance returned by this call. The consistency of the stored data is not guaranteed if you do, nor is your ability to modify the instance at all.

Это именно то, что вы делаете

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

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

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

Попробуйте создать Копию вашего набора, и вы можете сохранить ее в тех же привилегиях:

 private Set<String> _setFromPrefs; public void GetSetFromPrefs() { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); Set<String> someSets = sharedPref.getStringSet("some_sets", new HashSet<String>() ); _setFromPrefs = new HashSet<>(someSets); // THIS LINE CREATE A COPY } public void SaveSetsInPrefs() { SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences.Editor editor = sharedPref.edit(); editor.putStringSet("some_sets", _setFromPrefs); editor.commit(); } 

Согласно документу, String Set в SharedPreferences следует рассматривать как непреложный, вещи идут на юг, пытаясь изменить его. Работа была бы: Получить существующий набор, сделать его копию, обновить копию, а затем сохранить ее обратно в общие настройки, как это был новый набор.

 Set<String> feedbackSet = getFeedbacksSet(); if(feedbackSet == null){ feedbackSet = new HashSet<String>(); } //make a copy of the set, update the copy and save the copy Set<String> newFeedbackSet = new HashSet<String>(); JSONObject json = createJSONObjectfromFeedback(feedbackItem); newFeedbackSet.add(json.toString()); newFeedbackSet.addAll(feedbackSet); ed.putStringSet(CoreSetup.KEY_FEEDBACK, newFeedbackSet); ed.commit(); 

Чтобы сохранить строку в sharedprefernces

  SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this); editor.putString("text", mSaved.getText().toString()); editor.commit(); 

Чтобы получить данные из общих предпочтений

  SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); String restoredText = prefs.getString("text", null);