我注冊一個優先權來改變監聽器想這樣(在我的主activity的onCreate()中):
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(
SharedPreferences prefs, String key) {
System.out.println(key);
}
});
問題就是,監聽器並不能一直被調用。它只在最開始的幾次起作用,能夠讓優先權改變,然後就直到我卸載然後重新安裝引用程序他都不再被調用。重啟了應用程序很多次好像都不能修復。
怎麼才能解決呢?
這是一個很詭異的問題。SharedPreferences一直在WeakHashMap保持監聽。這意味著你不能用匿名的內部類作為監聽器,因為一旦你離開當前的范圍它將變成回收的目標。它將首先工作,但是最終,仍然要被回收,被從WeakHashMap移除然後停止工作。
在你的類中的一個位置引用一個監聽器,這樣就好了,提供你的類的實例也不會被銷毀。
也就是代替:
prefs.registerOnSharedPreferenceChangeListener(
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
}
});
這樣做:
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
}
};
prefs.registerOnSharedPreferenceChangeListener(listener);
在onDestroy方法取消注冊修復了這個問題,原因是因為這樣做你不得不在一個field保存一個監聽器,因此防止了這個問題的產生。這是在一個field保存這個監聽器來修復這個問題的方法,不是在onDestroy取消注冊。