Ich registriere einen Listener für Präferenzänderungen wie folgt (in onCreate()
meiner Hauptaktivität):
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(
SharedPreferences prefs, String key) {
System.out.println(key);
}
});
Das Problem ist, dass der Hörer nicht immer angerufen wird. Es funktioniert für die ersten Male, wenn eine Einstellung geändert wird, und wird dann nicht mehr aufgerufen, bis ich die App deinstalliere und neu installiere. Kein Neustart der Anwendung scheint das Problem zu beheben.
Ich habe einen Mailinglisten- Thread gefunden , der das gleiche Problem meldet, aber niemand hat ihm wirklich geantwortet. Was mache ich falsch?
quelle
Diese akzeptierte Antwort ist in Ordnung, da für mich jedes Mal, wenn die Aktivität fortgesetzt wird, eine neue Instanz erstellt wird
Wie wäre es also, wenn Sie den Verweis auf den Hörer innerhalb der Aktivität behalten?
und in Ihrem onResume und onPause
Dies wird sehr ähnlich zu dem sein, was Sie tun, außer dass wir eine harte Referenz beibehalten.
quelle
super.onResume()
vorher benutztgetPreferenceScreen()...
?super.onResume()
ist erforderlich ODER Verwendung, BEVORgetPreferenceScreen()
erforderlich ist? weil ich über den richtigen Ort spreche. cs.dartmouth.edu/~campbell/cs65/lecture05/lecture05.htmlthis
und nichtlistener
, hat sie Fehler verursacht und ich konnte mein Problem lösen. Übrigens sind diese beiden Methoden jetzt öffentlich und nicht geschütztDa dies die detaillierteste Seite für das Thema ist, möchte ich meine 50ct hinzufügen.
Ich hatte das Problem, dass OnSharedPreferenceChangeListener nicht aufgerufen wurde. Meine SharedPreferences werden zu Beginn der Hauptaktivität abgerufen von:
Mein PreferenceActivity-Code ist kurz und zeigt nur die Einstellungen an:
Jedes Mal, wenn die Menütaste gedrückt wird, erstelle ich die PreferenceActivity aus der Hauptaktivität:
Beachten Sie, dass die Registrierung des OnSharedPreferenceChangeListener in diesem Fall nach dem Erstellen der PreferenceActivity erfolgen muss, da sonst der Handler in der Hauptaktivität nicht aufgerufen wird !!! Ich brauchte einige süße Zeit, um zu erkennen, dass ...
quelle
Die akzeptierte Antwort erstellt
SharedPreferenceChangeListener
jedes Mal einenonResume
Aufruf. @Samuel löst das Problem , indem erSharedPreferenceListener
Mitglied der Aktivitätsklasse wird. Es gibt jedoch eine dritte und einfachere Lösung, die Google auch in diesem Codelab verwendet . Lassen Sie Ihre Aktivitätsklasse dieOnSharedPreferenceChangeListener
Schnittstelle implementieren undonSharedPreferenceChanged
in der Aktivität überschreiben , sodass die Aktivität selbst effektiv zu einer Aktivität wirdSharedPreferenceListener
.quelle
Kotlin-Code für das Register SharedPreferenceChangeListener erkennt, wann Änderungen am gespeicherten Schlüssel vorgenommen werden:
Sie können diesen Code in onStart () oder an einer anderen Stelle einfügen. * Beachten Sie, dass Sie ihn verwenden müssen
oder Ihre Codes im Block "// Do Something" werden bei jeder Änderung, die an einem anderen Schlüssel in sharedPreferences vorgenommen wird, falsch ausgeführt
quelle
Ich weiß also nicht, ob dies wirklich jemandem helfen würde, es hat mein Problem gelöst. Obwohl ich das
OnSharedPreferenceChangeListener
wie in der akzeptierten Antwort angegeben umgesetzt hatte . Trotzdem hatte ich eine Inkonsistenz mit dem angerufenen Hörer.Ich bin hierher gekommen, um zu verstehen, dass Android es nach einiger Zeit nur zur Speicherbereinigung sendet. Also schaute ich auf meinen Code. Zu meiner Schande hatte ich den Hörer nicht GLOBAL deklariert, sondern im
onCreateView
. Und das lag daran, dass ich mir das Android Studio angehört habe, in dem ich aufgefordert wurde, den Listener in eine lokale Variable umzuwandeln.quelle
Es ist sinnvoll, dass die Listener in WeakHashMap gespeichert bleiben. Da Entwickler es meistens vorziehen, den Code so zu schreiben.
Das mag nicht schlecht erscheinen. Wenn der Container von OnSharedPreferenceChangeListeners jedoch nicht WeakHashMap wäre, wäre dies sehr schlecht. Wenn der obige Code in einer Aktivität geschrieben wurde. Da Sie eine nicht statische (anonyme) innere Klasse verwenden, die implizit die Referenz der einschließenden Instanz enthält. Dies führt zu einem Speicherverlust.
Wenn Sie den Listener als Feld behalten, können Sie am Anfang registerOnSharedPreferenceChangeListener verwenden und am Ende unregisterOnSharedPreferenceChangeListener aufrufen . Sie können jedoch nicht auf eine lokale Variable in einer Methode außerhalb ihres Gültigkeitsbereichs zugreifen. Sie haben also nur die Möglichkeit, sich zu registrieren, aber keine Möglichkeit, die Registrierung des Hörers aufzuheben. Durch die Verwendung von WeakHashMap wird das Problem behoben. Dies ist der Weg, den ich empfehle.
Wenn Sie die Listener-Instanz als statisches Feld festlegen, wird der durch nicht statische innere Klasse verursachte Speicherverlust vermieden. Da die Listener jedoch mehrere sein können, sollte dies instanzbezogen sein. Dies reduziert die Kosten für die Bearbeitung des onSharedPreferenceChanged- Rückrufs.
quelle
Beim Lesen von Word-lesbaren Daten, die von der ersten App gemeinsam genutzt werden, sollten wir dies tun
Ersetzen
mit
in der zweiten App, um den aktualisierten Wert in der zweiten App zu erhalten.
Aber es funktioniert immer noch nicht ...
quelle