Estoy registrando un oyente de cambio de preferencia como este (en el onCreate()
de mi actividad principal):
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(
SharedPreferences prefs, String key) {
System.out.println(key);
}
});
El problema es que no siempre se llama al oyente. Funciona las primeras veces que se cambia una preferencia, y luego ya no se llama hasta que desinstale y vuelva a instalar la aplicación. Ninguna cantidad de reinicio de la aplicación parece solucionarlo.
Encontré un hilo de la lista de correo informando el mismo problema, pero nadie realmente le respondió. ¿Qué estoy haciendo mal?
fuente
esta respuesta aceptada está bien, ya que para mí está creando una nueva instancia cada vez que se reanuda la actividad
Entonces, ¿qué hay de mantener la referencia al oyente dentro de la actividad
y en tu onResume y onPause
Esto será muy similar a lo que está haciendo, excepto que mantenemos una referencia sólida.
fuente
super.onResume()
antesgetPreferenceScreen()...
?super.onResume()
que se requiera o utilizando este medicamento antesgetPreferenceScreen()
se requiere? porque estoy hablando del lugar CORRECTO. cs.dartmouth.edu/~campbell/cs65/lecture05/lecture05.htmlthis
y nolistener
, causó un error y pude resolver mi problema. Por cierto, estos dos métodos son públicos ahora, no están protegidosComo esta es la página más detallada para el tema, quiero agregar mi 50ct.
Tuve el problema de que no se llamaba a OnSharedPreferenceChangeListener. Mis preferencias compartidas se recuperan al comienzo de la actividad principal:
Mi código de PreferenceActivity es corto y no hace nada excepto mostrar las preferencias:
Cada vez que se presiona el botón de menú, creo la Actividad de Preferencia desde la Actividad principal:
Tenga en cuenta que el registro de OnSharedPreferenceChangeListener debe hacerse DESPUÉS de crear PreferenceActivity en este caso, de lo contrario, no se llamará al controlador en la actividad principal. Me tomó un tiempo dulce darme cuenta de que ...
fuente
La respuesta aceptada crea un
SharedPreferenceChangeListener
cada vez queonResume
se llama. @Samuel lo resuelve al hacerSharedPreferenceListener
un miembro de la clase Actividad. Pero hay una tercera y más sencilla solución que Google también usa en este codelab . Haga que su clase de actividad implemente laOnSharedPreferenceChangeListener
interfaz y anuleonSharedPreferenceChanged
la actividad, haciendo que la actividad en sí sea aSharedPreferenceListener
.fuente
Código de Kotlin para el registro SharedPreferenceChangeListener que detecta cuando se producirán cambios en la clave guardada:
puede poner este código en onStart (), o en otro lugar .. * Tenga en cuenta que debe usar
o sus códigos dentro del bloque "// Do Something" se ejecutarán incorrectamente para cada cambio que ocurra en cualquier otra clave en sharedPreferences
fuente
Entonces, no sé si esto realmente ayudaría a alguien, resolvió mi problema. A pesar de que había implementado lo
OnSharedPreferenceChangeListener
que dice la respuesta aceptada . Aún así, tuve una inconsistencia con la llamada del oyente.Vine aquí para entender que el Android simplemente lo envía para la recolección de basura después de algún tiempo. Entonces, miré mi código. Para mi vergüenza, no había declarado al oyente GLOBALMENTE, sino dentro del
onCreateView
. Y eso fue porque escuché a Android Studio diciéndome que convirtiera el oyente a una variable local.fuente
Tiene sentido que los oyentes se mantengan en WeakHashMap. Debido a que la mayoría de las veces, los desarrolladores prefieren escribir el código de esta manera.
Esto puede parecer no está mal. Pero si el contenedor de OnSharedPreferenceChangeListeners no fuera WeakHashMap, sería muy malo si el código anterior se escribiera en una actividad. Como está utilizando una clase interna no estática (anónima) que implícitamente contiene la referencia de la instancia de cierre. Esto causará pérdida de memoria.
Además, si mantiene el oyente como un campo, puede usar registerOnSharedPreferenceChangeListener al principio y llamar a unregisterOnSharedPreferenceChangeListener al final. Pero no puede acceder a una variable local en un método fuera de su alcance. Por lo tanto, solo tiene la oportunidad de registrarse, pero no la posibilidad de cancelar el registro del oyente. Por lo tanto, usar WeakHashMap resolverá el problema. Esta es la forma que recomiendo.
Si realiza la instancia de escucha como un campo estático, evitará la pérdida de memoria causada por la clase interna no estática. Pero como los oyentes podrían ser múltiples, debería estar relacionado con la instancia. Esto reducirá el costo de manejar la devolución de llamada onSharedPreferenceChanged .
fuente
Al leer los datos legibles de Word compartidos por la primera aplicación, deberíamos
Reemplazar
con
en la segunda aplicación para obtener un valor actualizado en la segunda aplicación.
Pero aún así no está funcionando ...
fuente