android - studio - getsharedpreferences
Conjunto de cadenas de Android SharedPreferences: algunos elementos se eliminan despuĆ©s de reiniciar la aplicaciĆ³n (6)
Guardo un conjunto de cadenas en las preferencias compartidas, si lo leo, está bien. Comienzo otras actividades, vuelvo a leerlo, está bien. Si cierro la aplicación y la vuelvo a iniciar, obtengo el conjunto, pero con solo 1 elemento en lugar de 4. Pasa todo el tiempo. ¿Hay algún problema conocido? ¿Qué podría hacer mal?
En una clase, lo que se crea en el método oncreate de la aplicación tengo una SharedPreferences y una variable SharePreferences.Editor. Los uso en los métodos de guardar y cargar.
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();
}
Simplemente no puedo entender cómo podría suceder, para almacenar perfectamente todos los elementos mientras la aplicación se está ejecutando, luego de un reinicio no todos los elementos están en el conjunto. Y creo que si se eliminan todos los elementos, podría ser más aceptable que algunos artículos se han ido, y un elemento todavía está allí. Hay una explicación?
De acuerdo con el documento, el Conjunto de Cadenas en SharedPreferences debe tratarse como inmutable, las cosas van al sur cuando se intenta modificarlo. Una solución alternativa sería: obtener el conjunto existente, hacer una copia del mismo, actualizar la copia y luego guardarla nuevamente en las preferencias compartidas como si fuera un conjunto nuevo.
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();
Este "problema" está documentado en SharedPreferences.getStringSet()
.
getStringSet () devuelve una referencia del objeto HashSet almacenado dentro de SharedPreferences. Cuando agrega elementos a este objeto, se agregan de hecho dentro de SharedPreferences.
La solución consiste en hacer una copia del conjunto devuelto y colocar el nuevo conjunto en SharedPreferences. Lo probé y funciona.
En Kotlin, eso sería
val setFromSharedPreferences = sharedPreferences.getStringSet("key", mutableSetOf())
val copyOfSet = setFromSharedPreferences.toMutableSet()
copyOfSet.add(addedString)
val editor = sharedPreferences.edit()
editor.putStringSet("key", copyOfSet)
editor.apply() // or commit() if really needed
Intenta crear una Copia de tu conjunto, y entonces puedes guardarlo en las mismas preferencias:
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();
}
Para guardar una cadena en preferencias compartidas
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(this);
editor.putString("text", mSaved.getText().toString());
editor.commit();
Para recuperar datos de preferencias compartidas
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String restoredText = prefs.getString("text", null);
Se encontró con este mismo problema. Lo resolvió borrando el editor después de crear instancias y antes de comprometerse.
sPrefs = PreferenceManager.getDefaultSharedPreferences(context);
sFavList = sPrefs.getStringSet(context.getResources().getString(R.string.pref_fav_key), null);
sEditor = sPrefs.edit();
sEditor.clear(); // added clear, now Set data persists as expected
if (sFavList == null) sFavList = new HashSet<>();
sFavList.add(title);
sEditor.putStringSet(context.getResources().getString(R.string.pref_fav_key), sFavList).apply();
Traté de crear una copia como otros sugirieron, pero eso no funcionó para mí.
Encontré esta solución here .
Según su pregunta, debe invocar la confirmación solo después de que se hayan agregado 4 elementos al conjunto. En su código, llama a commit para cada comentario que sobrescribirá los comentarios anteriores.
Actualización : 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.
Esto es exactamente lo que estás haciendo