Rejestruję odbiornik zmiany preferencji w ten sposób (w onCreate()
mojej głównej działalności):
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(
SharedPreferences prefs, String key) {
System.out.println(key);
}
});
Problem w tym, że słuchacz nie zawsze jest wywoływany. Działa po raz pierwszy, gdy preferencje są zmieniane, a następnie nie są wywoływane, dopóki nie odinstaluję i ponownie nie zainstaluję aplikacji. Wydaje się, że żadna ilość ponownego uruchomienia aplikacji nie naprawi tego.
Znalazłem wątek na liście mailingowej zgłaszający ten sam problem, ale tak naprawdę nikt mu nie odpowiedział. Co ja robię źle?
źródło
ta zaakceptowana odpowiedź jest w porządku, ponieważ dla mnie tworzy ona nową instancję za każdym razem, gdy aktywność zostanie wznowiona
co powiesz na zachowanie odniesienia do słuchacza w ramach działania
oraz w onResume i onPause
będzie to bardzo podobne do tego, co robisz, z wyjątkiem tego, że utrzymujemy twarde referencje.
źródło
super.onResume()
wcześniejgetPreferenceScreen()...
?super.onResume()
jest wymagane LUB korzystanie z niego PRZEDgetPreferenceScreen()
jest wymagane? ponieważ mówię o właściwym miejscu. cs.dartmouth.edu/~campbell/cs65/lecture05/lecture05.htmlthis
i nielistener
, spowodowało to błąd i mogłem rozwiązać mój problem. Btw te dwie metody są teraz publiczne, nie chronionePonieważ jest to najbardziej szczegółowa strona tematu, chcę dodać 50ct.
Miałem problem, że nie wywołano OnSharedPreferenceChangeListener. Moje współdzielone preferencje są pobierane na początku głównej aktywności przez:
Mój kod preferencji jest krótki i nie robi nic poza pokazaniem preferencji:
Za każdym naciśnięciem przycisku menu tworzę PreferenceActivity z głównego działania:
Należy pamiętać, że rejestracja OnSharedPreferenceChangeListener musi zostać wykonana PO utworzeniu PreferenceActivity w tym przypadku, w przeciwnym razie moduł obsługi w głównym działaniu nie zostanie wywołany !!! Uświadomienie sobie, że ...
źródło
Zaakceptowana odpowiedź tworzy za
SharedPreferenceChangeListener
każdym razem, gdyonResume
jest wywoływana. @Samuel rozwiązuje to, czyniącSharedPreferenceListener
członka klasy Activity. Ale istnieje trzecie i prostsze rozwiązanie, którego Google używa również w tym kodzie kodowym . Spraw, aby klasa działań implementowałaOnSharedPreferenceChangeListener
interfejs i zastępowałaonSharedPreferenceChanged
działanie, skutecznie czyniąc samo działanieSharedPreferenceListener
.źródło
Kod Kotlin dla rejestru SharedPreferenceChangeListener wykrywa, kiedy nastąpi zmiana na zapisanym kluczu:
możesz umieścić ten kod w onStart () lub w innym miejscu .. * Zastanów się, że musisz użyć
lub kody wewnątrz bloku „// Zrób coś” będą uruchamiane niepoprawnie dla każdej zmiany, która nastąpi w dowolnym innym kluczu w sharePreferences
źródło
Więc nie wiem, czy to naprawdę komukolwiek by pomogło, rozwiązało to mój problem. Mimo że
OnSharedPreferenceChangeListener
wdrożyłem zgodnie z przyjętą odpowiedzią . Mimo to miałem niespójność z wezwaniem słuchacza.Przyszedłem tutaj, aby zrozumieć, że Android po prostu wysyła go do śmieci po pewnym czasie. Spojrzałem na mój kod. Ku mojemu wstydowi nie zadeklarowałem GLOBALNIE słuchacza, ale zamiast tego w
onCreateView
. A to dlatego, że słuchałem Android Studio z poleceniem konwersji odbiornika na zmienną lokalną.źródło
Ma to sens, że nasłuchiwania są przechowywane w WeakHashMap, ponieważ przez większość czasu programiści wolą pisać taki kod.
To może wydawać się niezłe. Ale jeśli kontener OnSharedPreferenceChangeListeners nie był WeakHashMap, byłoby bardzo źle. Jeśli powyższy kod został napisany w działaniu. Ponieważ używasz niestatycznej (anonimowej) klasy wewnętrznej, która niejawnie przechowuje odwołanie do otaczającej instancji. Spowoduje to wyciek pamięci.
Co więcej, jeśli trzymasz detektor jako pole, możesz użyć registerOnSharedPreferenceChangeListener na początku i wywołać unregisterOnSharedPreferenceChangeListener na końcu. Ale nie można uzyskać dostępu do zmiennej lokalnej w metodzie spoza jej zakresu. Masz więc tylko możliwość zarejestrowania się, ale nie ma możliwości wyrejestrowania słuchacza. Zatem użycie WeakHashMap rozwiąże problem. Tak właśnie polecam.
Jeśli utworzysz instancję detektora jako pole statyczne, unikniesz wycieku pamięci spowodowanego przez niestatyczną klasę wewnętrzną. Ale ponieważ nasłuchiwanie może być wielokrotne, powinno być związane z instancją. Zmniejszy to koszty obsługi wywołania zwrotnego onSharedPreferenceChanged .
źródło
Podczas czytania danych czytelnych dla programu Word udostępnianych przez pierwszą aplikację, powinniśmy
Zastąpić
z
w drugiej aplikacji, aby uzyskać zaktualizowaną wartość w drugiej aplikacji.
Ale nadal nie działa ...
źródło