Usar SharedPreferences en modo multiproceso

He definido una instancia de SharedPreferences que se utiliza en el modo multi-proceso.

 public class Prefs { private static SharedPreferences prefs; private static SharedPreferences.Editor editor; private static void init(Context context) { prefs = context.getSharedPreferences("alaki", Context.MODE_MULTI_PROCESS); editor = prefs.edit(); } // static methods to set and get preferences } 

Ahora estoy usando esta clase en un servicio con proceso separado y también en mi proceso de aplicación principal de manera estática.
Todo va bien, pero a veces todos los datos almacenados en la instancia SharedPreferences eliminado!
¿Como puedó resolver esté problema?

Edit: Finalmente he resuelto mi problema usando por IPC.

Actualmente no hay forma de acceder de forma segura a SharedPreferences en múltiples procesos, como se describe en su documentación .

Nota: actualmente esta clase no admite el uso a través de múltiples procesos. Esto se agregará más tarde.

Después de probar mucho con MODE_MULTI_PROCESS , tengo tres ensayos para compartir:

1- Inicializar las SharedPreferences una vez en cada proceso y usarlo varias veces.

El problema: Los valores no se reflejan en cada proceso como se esperaba. Así que cada proceso tiene su propio valor de SharedPreferences.

2- Inicializar las SharedPreferences en cada put o get.

Esto realmente funciona y el valor ahora es intercambiable entre procesos.

El problema: a veces, después de acceder agresivamente al sharedpref, el archivo de preferencias compartidas se eliminó con todo su contenido, como se describe en este número , y recibo esta advertencia en el registro:

 W/FileUtils﹕ Failed to chmod(/data/data/com.hegazy.multiprocesssharedpref/shared_prefs/myprefs.xml): android.system.ErrnoException: chmod failed: ENOENT (No such file or directory) 

Puede averiguar por qué sucede esto en el problema.

3- Utilice la sincronización para bloquear los métodos que ponen y obtienen valores en SharedPreferences .

Esto es completamente incorrecto; La sincronización no funciona en todos los procesos. SharedPreferences utiliza en realidad la sincronización en su implementación, pero sólo garantiza la seguridad de los subprocesos, no la seguridad del proceso. Esto se describe muy bien aquí .

SharedPreferences no es un proceso seguro. Eso es probablemente por qué la documentación de SharedPreferences dice

Nota: actualmente esta clase no admite el uso a través de múltiples procesos. Esto se agregará más tarde.

He trabajado en torno a esto mediante la combinación de:

  • Proporcionar a cada proceso un acceso mutuamente exclusivo al archivo SharedPreferences (por ejemplo, mediante un mecanismo de bloqueo basado en socket )
  • SharedPreferences las SharedPreferences con el indicador MODE_MULTI_PROCESS cada vez que lo desee para omitir la memoria caché en memoria

Esto parece funcionar bien, pero no ha sido probado a fondo en el mundo real, así que no sé si es perfectamente confiable.

Puedes ver un ejemplo de trabajo que escribí aquí .

Advertencia : Parece que MODE_MULTI_PROCESS ha quedado obsoleto en Android M. Podría dejar de funcionar en el futuro.

Usando el método commit() almacenar los cambios en el almacenamiento persistente, por lo que es lento y haría que el conflicto a través de múltiples llamadas de otros procesos.

Sin embargo hay una alternativa a este método, debe llamar al método apply() , este método almacena los cambios en la memoria y luego en el almacenamiento de disco de forma asíncrona, por lo que es más fiable.

Recuerda que el uso de objetos de contexto como campo estático, tiene el riesgo de fuga de contexto porque no declarar el objeto en la clase de aplicación

 public class CustomApplication extends Application{ private Prefs prefs; public void onCreate(){ prefs = new Prefs(this); } public Prefs getPrefs(){ return prefs; } } 

Desde cualquier contexto se pueden obtener las preferencias

  ((MyApplication)context.getApplicationContext()).getPrefs(); 

Utilice un proveedor de contenido que utilice SharedPreferences. Ejemplo vea aquí: https://github.com/hamsterksu/MultiprocessPreferences

Si dos procesos escriben datos en SharedPreferences, es posible que todas las SharedPreferences se restablezcan a valores predeterminados.

También puede intentar llamar a clear() en el editor antes de almacenar val

 SharedPreferences.Editor sp = settings.edit(); sp.clear(); sp.putString("Name", "YourName"); sp.commit(); 
  • SharedPreferences Borrar / Guardar
  • Android: ¿Configurar las preferencias compartidas durante la instalación?
  • Excepción de puntero nulo de Android para las preferencias compartidas
  • ¿Está bien para guardar una matriz JSON en SharedPreferences?
  • Android Preferencias compartidas ejemplo
  • Obtener todos los nombres SharedPreferences y todas sus claves?
  • Serializar un SparseArray <T> con GSON
  • ¿Cuál es la mejor manera de guardar el contenido de una ArrayList?
  • Expectativa de puntero nulo al obtener valores de preferencia compartida
  • Copia de seguridad de SharedPreferences de Android no funciona
  • Android, sharedferencias o almacenamiento interno?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.