OnSharedPreferenceChanged no se dispara si se produce un cambio en una actividad independiente?

He implementado onSharedPreferenceChanged en mi actividad principal.

Si cambio las preferencias en la actividad principal, se dispara mi evento.

Si cambio las preferencias a través de mi pantalla de preferencias ( PreferenceActivity ), mi evento NO se activa cuando se cambian las preferencias (porque es una actividad separada y una referencia separada a SharedPreferences?)

¿Alguien tiene una recomendación de cómo debo ir sobre la superación de esta situación?

¡Gracias!

EDIT1: He intentado agregar el manejador de eventos justo en mi actividad de preferencia pero nunca se dispara. El método siguiente se llama durante onCreate de mi actividad de preferencia. Cuando cambio valores, nunca imprime el mensaje ( msg() es un envoltorio para Log.d ).

 private void registerChangeListener () { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); sp.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener () { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { msg (" ***** Shared Preference Update ***** "); Intent i = new Intent(); i.putExtra("KEY", key); i.setAction("com.gtosoft.dash.settingschanged"); sendBroadcast(i); // TODO: fire off the event } }); } 

El OnSharedPreferenceChangeListener obtiene la basura recopilada en su caso si utiliza una clase anónima.

Para resolver ese problema, utilice el siguiente código en PreferenceActivity para registrar y anular el registro de un detector de cambios:

 public class MyActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { @Override protected void onResume() { super.onResume(); // Set up a listener whenever a key changes getPreferenceScreen().getSharedPreferences() .registerOnSharedPreferenceChangeListener(this); } @Override protected void onPause() { super.onPause(); // Unregister the listener whenever a key changes getPreferenceScreen().getSharedPreferences() .unregisterOnSharedPreferenceChangeListener(this); } public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) { // do stuff } 

Además, tenga en cuenta que el oyente sólo se llama si el valor real cambia. Si vuelve a establecer el mismo valor, no se disparará el oyente.

Consulte también SharedPreferences.onSharedPreferenceChangeListener no se llama de forma coherente

Esto sucede porque el recolector de basura. Su obra sólo una vez. Entonces la referencia se recoge como basura. Así que cree el campo de la instancia para el oyente.

 private OnSharedPreferenceChangeListener listner; listner = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { //implementation goes here } }; prefs.registerOnSharedPreferenceChangeListener(listner); 

Llegué aquí, como muchos otros, porque mi oyente no será despedido cuando cambié mi booleano de true a false , o viceversa.

Después de mucha lectura y refactorización, cambiando contexts/inner classes/privates/static/ contexts/inner classes/privates/static/ y similares, me di cuenta de mi error (estúpido):

El onSharedPreferenceChanged sólo se llama si algo cambia. Solamente. Nunca.

Durante mis pruebas, era tan tonto hacer clic en el mismo botón todo el tiempo, asignando así el mismo valor booleano a la preferencia todo el tiempo, por lo que no cambió nunca.

Espero que esto ayude a alguien !!

Otra forma de evitar el problema es hacer de su actividad la clase de escucha. Dado que sólo hay un método de sustitución con un nombre distintivo, puede hacerlo:

 public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sharedPreferences.registerOnSharedPreferenceChangeListener(this); ... } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { ... } } 

Tenga en cuenta que la pregunta original habló de MainActivity escuchando los cambios de configuración en una PreferenceActivity. El asker entonces añadió un "EDIT1" y cambió la pregunta a escuchar en la propia PreferenceActivity. Eso es más fácil que el primero y parece ser lo que todas las respuestas asumen. Pero, ¿y si todavía quieres el escenario anterior?

Bueno, también funcionará, pero no utilice OnResume () y OnPause () para registrar y anular el registro del oyente. Hacerlo hará que el oyente sea ineficaz porque el usuario abandona MainActivity cuando usan PreferenceActivity (lo cual tiene sentido cuando piensa en ello). Así que funcionará, pero luego MainActivity seguirá escuchando en segundo plano incluso cuando el usuario no lo esté usando. Tipo de un desperdicio de recursos ¿no? Así que hay otra solución que parece funcionar, simplemente agregue un método a OnResume () para volver a leer todas las preferencias. De esta forma, cuando un usuario termine de editar las preferencias en una PreferenciaActividad, MainActivity los recogerá cuando el usuario vuelva a ella y no necesite un oyente en absoluto .

Alguien por favor hágamelo saber si ven un problema con este acercamiento.

Mientras lee los datos legibles de Word compartidos por la primera aplicación, debemos

Reemplazar

 getSharedPreferences("PREF_NAME", Context.MODE_PRIVATE); 

con

 getSharedPreferences("PREF_NAME", Context.MODE_MULTI_PROCESS); 

En la segunda aplicación para obtener el valor actualizado en la segunda aplicación.

¿Por qué no añade un onSharedPreferenceChanged en el resto de las actividades donde las preferencias podrían cambiar?

El recolector de basura borra que … usted debe considerar el uso de un contexto de la aplicación en su lugar … o simplemente agregar el código cuando se inicia la aplicación … y luego agregar el listener con el contexto de la aplicación …

  • Poner y obtener la matriz de cadenas de las preferencias compartidas
  • Leer la preferencia compartida cuando se cambia el contexto
  • Escritura de clase Singleton para administrar las compartidas SharedPreferences de Android
  • ¿Cómo uso las preferencias de los fragmentos con ViewPager?
  • Advertencia de método obsoleto de Android con respecto a PreferenceActivity
  • Android getDefaultSharedPreferences
  • Borrar el archivo SharedPreferences
  • Android SharedPreferences sin guardar
  • ¿Cuándo se creó por primera vez un archivo de preferencias compartidas?
  • Guardar matriz de bytes con SharedPreferences
  • Cómo burlar una SharedPreferences usando Mockito
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.