共享preferences.onShared preferenceChangeListener不会被调用一致 [英] SharedPreferences.onSharedPreferenceChangeListener not being called consistently

查看:124
本文介绍了共享preferences.onShared preferenceChangeListener不会被调用一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注册(我的主要活动中的onCreate())一个preference变化监听器是这样的:

I'm registering a preference change listener like this (in the onCreate() of my main activity):

SharedPreferences prefs = 
    PreferenceManager.getDefaultSharedPreferences(this);

prefs.registerOnSharedPreferenceChangeListener(
    new SharedPreferences.OnSharedPreferenceChangeListener() {
        public void onSharedPreferenceChanged(
            SharedPreferences prefs, String key) {

            System.out.println(key);
        }
    });

麻烦的是,听众并不总是叫。它的工作原理是第几次preference被改变,那么它不再叫,直到我卸载并重新安装应用程序。重新启动应用程序再多似乎解决它。

The trouble is, the listener is not always called. It works for the first few times a preference is changed, and then it is no longer called until I uninstall and reinstall the app. No amount of restarting the application seems to fix it.

我发现了一个邮件列表线程报告了同样的问题,但没有一个人真正回答他。我究竟做错了什么?

I found a mailing list thread reporting the same problem, but no one really answered him. What am I doing wrong?

推荐答案

这是偷偷摸摸的。共享preferences保持听众WeakHashMap中。这意味着你不能使用匿名内部类作为侦听器,因为它会成为垃圾收集的目标,一旦你离开目前的范围。它将工作在第一,但最终会得到垃圾收集,从WeakHashMap中删除并停止工作。

This is a sneaky one. SharedPreferences keeps listeners in a WeakHashMap. This means that you cannot use an anonymous inner class as a listener, as it will become the target of garbage collection as soon as you leave the current scope. It will work at first, but eventually, will get garbage collected, removed from the WeakHashMap and stop working.

请参考给听者在你的类的领域,你会好的,只要你的类的实例不被破坏。

Keep a reference to the listener in a field of your class and you will be OK, provided your class instance is not destroyed.

即。而不是:

prefs.registerOnSharedPreferenceChangeListener(
  new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // Implementation
  }
});

做到这一点:

do this:

// Use instance field for listener
// It will not be gc'd as long as this instance is kept referenced
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // Implementation
  }
};

prefs.registerOnSharedPreferenceChangeListener(listener);

原因注销了的onDestroy方法解决了这个问题,因为这样做,你必须保存听众在一个领域,因此preventing问题。这是保存监听器在解决问题,而不是对的onDestroy注销的字段。

The reason unregistering in the onDestroy method fixes the problem is because to do that you had to save the listener in a field, therefore preventing the issue. It's the saving the listener in a field that fixes the problem, not the unregistering in onDestroy.

更新:Android的文档已经<一个href="http://developer.android.com/reference/android/content/Shared$p$pferences.html#registerOnShared$p$pferenceChangeListener%28android.content.Shared$p$pferences.OnShared$p$pferenceChangeListener%29">updated与警告的有关此问题。因此,古怪的行为仍然存在。但现在它的记录。

UPDATE: The Android docs have been updated with warnings about this behavior. So, oddball behavior remains. But now it's documented.

这篇关于共享preferences.onShared preferenceChangeListener不会被调用一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆