example - sharedpreferences android kotlin
¿Cuándo devuelve false(SharedPreferences) de Android? (4)
En mi aplicación, estoy almacenando algunos datos en SharedPreferences
, funciona según sea necesario. Ahora quiero crear mensajes de registro para algunas situaciones incorrectas.
Manejé con éxito situaciones donde las preferencias están vacías o lanzan alguna excepción al cargar. El único error que puede aparecer mientras se guardan los valores es que commit()
devuelve false
: no sé por qué podría suceder esto y qué debo hacer en ese caso.
Entonces mi pregunta es: ¿Cuándo el método commit()
devuelve false
? ¿Y qué debo hacer en ese caso? ¿Podría ser una posible solución llamar a commit()
una y otra vez (algo así como while (!editor.commit()) {}
)?
¿Y puede while (! Editor.commit ()) {;} ser la solución para el éxito de todos modos?
La operación ''commit'' es sincrónica y se realiza en el subproceso de la interfaz de usuario, por lo tanto, si tiene un error irrecuperable que ocurre cada vez que intenta realizar un commit
, bloqueará todo su subproceso de UI con este código y el usuario verá ANR. No está bien.
''aplicar'', por otro lado, es asíncrono, por lo tanto, no puede bloquear el hilo de la IU incluso si lo realizarás indefinidamente.
La documentación dice muy poco acerca de los posibles fallos de la operación de "confirmación" (consulte here , here y here ). Las preferencias se almacenan dentro del archivo xml almacenado en su almacenamiento interno, por lo que una posible falla puede ser el archivo xml dañado. El segundo se puede encontrar en la here :
Tenga en cuenta que cuando dos editores modifican las preferencias al mismo tiempo, el último en llamar a confirmación gana.
Es poco lo que puede hacer sobre el archivo dañado y, bueno, no intente modificar las preferencias de diferentes lugares al mismo tiempo. :)
Estaría abordando este problema desde otro ángulo por completo.
Hay un par de formas alternativas para lidiar con esto.
Lo que hago es cuando mi programa se ejecuta por primera vez, inicializo mi valor de preferencia compartido a un valor de prueba para que compruebe si se ha cambiado.
p.ej:
editor.putInt("key", -1);
Luego en la actividad donde estoy recuperando el valor de la preferencia:
int mySavedInt = this.pref.getInt("key", howIgetMyInt)
if(mySavedInt==-1){
// I know it''s not my saved int :) and hasn''t been set.
}
O bien, para usar realmente una preferencia compartida para determinar si las preferencias compartidas que intenta validar se han actualizado.
p.ej.
String getStatus = pref.getString("checkMySharedPreferences", "nil");
if (getStatus.equals("true")) {
// DO something.
} else {
Toast.makeText(this, "Set your preferences",
Toast.LENGTH_SHORT).show();
}
Luego, cuando establece sus preferencias compartidas, puede establecer este valor en "verdadero":
editor.putString("checkMySharedPreferences", "true");
editor.commit();
Otra sugerencia es asegurarse de validar los datos antes de actualizar sus preferencias compartidas. De esa manera, las preferencias compartidas no se establecerán si los datos no son válidos.
if(my data is valid){
my shared preferences
commit
}
La sugerencia final es hacer una verificación cíclica (ya que está inseguro en el proceso) y cuando obtiene sus datos para las preferencias compartidas y las confirma. Compruebe que la entrada del usuario es igual a las nuevas preferencias compartidas. Aunque no veo esto como necesario.
Y para registrar estos eventos, simplemente agregue sus líneas de registro donde corresponda.
Además, solo una nota al margen, no creo que sea necesariamente una buena práctica lanzar una excepción si no están configuradas, creo que la administración del flujo del programa se puede manejar mejor con sentencias condicionales donde es obvio que habrá un error de runtime
. Guarde el manejo de errores al validar la entrada del usuario.
Primero, nunca querría hacer: while(!editor.commit()) {;}
. Si desea volver a intentar un compromiso, lo haría varias veces en lugar de hacer un ciclo para siempre.
Con respecto a cuándo commit () devuelve -1: tanto commit () como apply () realizan los cambios en la memoria y luego realizan las llamadas para escribir los cambios en el disco ( por fuente ). commit () espera a que la escritura del disco vuelva para devolver los resultados. Entonces, la respuesta a su pregunta es: "Cuando se guarda el estado de preferencia en el disco falla para su llamada a commit () en particular". Dado que los cambios se reflejaron en la memoria, pueden o no pueden escribirse en el disco mediante otra llamada commit () o apply () antes o después de su intento de escritura en el disco (piense en los temas de carreras). Dado que no hay código para revertir la actualización de la memoria y SharedPreferences son singletons ( por fuente ), otros componentes en su aplicación verán sus cambios incluso si no se guardaron en el disco.
En resumen, hacer un bucle unas cuantas veces (no para siempre) para garantizar que las escrituras commit () en el disco parezcan adecuadas para superar un problema de E / S intermitente, pero sería una situación rara basada en E / S en la que falla. Si necesita un alcance de confirmación perfecto, desearía volver a leer el disco para validar cada llamada de confirmación () que tiene implicaciones de rendimiento y es una exageración para todas las situaciones, excepto para un pequeño conjunto.
commit()
puede devolver falso si hay un problema al guardar sus datos.
Mire la diferencia entre commit()
y apply()
para obtener una idea más clara (tomada de este sitio )
aplicar()
Esto guarda sus datos en la memoria inmediatamente y guarda los datos en el disco en un hilo separado. Por lo tanto, no hay posibilidad de bloquear el hilo principal (su aplicación no se bloquea).
Es la técnica preferida, pero solo ha estado disponible desde Gingerbread (API 9, Android 2.3).
cometer()
Al llamar a esto se guardarán los datos en el archivo; sin embargo, el proceso se lleva a cabo en el hilo que lo llamó, deteniendo todo lo demás hasta que se complete el proceso de guardado. Retorna verdadero al completarse exitosamente, falso al fallar.
Utilice commit () si necesita la confirmación del éxito al guardar sus datos o si está desarrollando dispositivos pre-Gingerbread. commit () ha estado disponible desde la API 1