from - sharedpreferences android kotlin
onSharedPreferenceChanged no se activa si el cambio ocurre en una actividad separada? (8)
¿Por qué no agrega un onSharedPreferenceChanged
en el resto de las actividades donde las preferencias podrían cambiar?
Implementé onSharedPreferenceChanged
en mi actividad principal.
Si cambio las preferencias en la actividad principal, mi evento se dispara.
Si cambio las preferencias a través de mi pantalla de preferencias ( PreferenceActivity
), mi evento NO se activa cuando cambian las preferencias (porque es una actividad separada y una referencia separada a sharedPreferences?)
¿Alguien tiene una recomendación de cómo debería hacer para superar esta situación?
¡Gracias!
EDIT1: Intenté agregar el controlador de eventos directamente en mi actividad preferida, pero nunca se dispara. Se llama al siguiente método durante onCreate de mi actividad de preferencia. Cuando cambio valores, nunca imprime el mensaje ( msg()
es un contenedor 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
}
});
}
Al leer datos legibles por Word compartidos por la primera aplicación, deberíamos
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.
El recolector de basura borra eso ... debería considerar usar un contexto de aplicación en su lugar ... o simplemente agregar el código cuando la aplicación se inicia ... y luego agregar el oyente con el contexto de la aplicación ...
Esto sucede porque el recolector de basura. funciona solo una vez. entonces la referencia se recoge como basura. así que crea un campo de 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 cambie mi booleano de true
a false
, o viceversa.
Después de leer mucho, refactorizar, cambiar contexts/inner
classes/privates/static/
contexts/inner
classes/privates/static/
etc., me di cuenta de mi (estúpido) error:
El onSharedPreferenceChanged
solo se onSharedPreferenceChanged
si algo cambia. Solamente. Nunca.
Durante mis pruebas, fui tan tonto al 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 nunca cambió.
Espero que esto ayude a alguien !!
Otra forma de evitar el problema es convertir su actividad en la clase de oyentes. Como solo hay un método de sustitución con un nombre distintivo, puede hacer esto:
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 hablaba de una actividad principal escuchando los cambios de configuración en una actividad de preferencia. El asker luego agregó un "EDIT1" y cambió la pregunta a escuchar en la actividad de preferencia en sí. Eso es más fácil que el primero y parece ser lo que asumen todas las respuestas. Pero, ¿y si aún quieres el escenario anterior?
Bueno, funcionará también, pero no use OnResume () y OnPause () para registrar y anular el registro del oyente. Hacerlo hará que el oyente sea ineficaz porque el usuario abandona la actividad principal cuando usa la actividad de preferencia (que tiene sentido cuando lo piensas). Por lo tanto, funcionará, pero su MainActivity seguirá escuchando en segundo plano incluso cuando el usuario no lo esté utilizando. Una especie de desperdicio de recursos, ¿no? Entonces, hay otra solución que parece funcionar, simplemente agregue un método a OnResume () para volver a leer todas las preferencias. De esta manera, cuando un usuario finaliza las preferencias de edición en una actividad de preferencia, MainActivity las recogerá cuando el usuario regrese a ella y no necesita un oyente en absoluto .
Alguien por favor avíseme si ven un problema con este enfoque.
OnSharedPreferenceChangeListener
obtiene basura recolectada en su caso si usa una clase anónima.
Para resolver ese problema, use 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 solo recibe una llamada si el valor real cambia. Establecer el mismo valor nuevamente no disparará al oyente.
ver también SharedPreferences.onSharedPreferenceChangeListener no se llama constantemente