android service multiprocessing sharedpreferences ipc

android - Use SharedPreferences en modo multiproceso



service multiprocessing (7)

recuerda que el uso de objetos de contexto como campo estático, tiene el riesgo de fuga de contexto porque no declara 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, puedes obtener los prefs

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

SharedPreferences una instancia de SharedPreferences que se usaba en el modo multiproceso.

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 principal de aplicación de manera estática.
Todo va bien, pero a veces se eliminan todos los datos almacenados en la instancia de SharedPreferences.
¿Como puedó resolver esté problema?

Editar: Finalmente resolví mi problema usando IPC.


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

También puedes intentar llamar a clear() en el editor antes de guardar val

SharedPreferences.Editor sp = settings.edit(); sp.clear(); sp.putString("Name", "YourName"); sp.commit();


SharedPreferences en sí no es seguro para el proceso. Esa es probablemente la razón por la cual la documentación de SharedPreferences dice

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


El uso del método commit() almacena los cambios en el almacenamiento persistente, por lo tanto, es lento y generaría conflictos entre llamadas múltiples desde otros procesos.

Sin embargo, existe 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 en disco de forma asíncrona, por lo que es más confiable.



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 en múltiples procesos. Esto se agregará más tarde.

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

1- Inicialice SharedPreferences una vez en cada proceso y utilícelo varias veces.

El problema: los valores no se reflejan en cada proceso como se esperaba. Por lo tanto, cada proceso tiene su propio valor de SharedPreferences.

2- Inicializar las SharedPreferences en cada put u get.

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

El problema: a veces, después de acceder de forma agresiva a sharedpref, el archivo de preferencias compartidas se elimina con todo su contenido, como se describe en este número , y aparece 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)

Puedes encontrar 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 está utilizando la sincronización en su implementación, pero eso solo garantiza la seguridad del hilo, no la seguridad del proceso. Esto se describe muy bien aquí .


He trabajado alrededor de esto combinando:

  • Proporcionar a cada proceso acceso mutuamente exclusivo al archivo SharedPreferences (como mediante el uso de un mecanismo de bloqueo basado en sockets )
  • SharedPreferences con el indicador MODE_MULTI_PROCESS cada vez que quiera usarlo para eludir el almacenamiento en memoria caché en memoria

Esto parece funcionar bien, pero no ha sido probado exhaustivamente 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.