woshiwoxingfu 2012-10-25 03:14 采纳率: 100%
浏览 5948
已采纳

SharedPreferences.onSharedPreferenceChangeListener不能一直被调用

我注册一个优先权来改变监听器想这样(在我的主activity的onCreate()中):

SharedPreferences prefs = 
    PreferenceManager.getDefaultSharedPreferences(this);

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

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

问题就是,监听器并不能一直被调用。它只在最开始的几次起作用,能够让优先权改变,然后就直到我卸载然后重新安装引用程序他都不再被调用。重启了应用程序很多次好像都不能修复。
怎么才能解决呢?

  • 写回答

2条回答 默认 最新

  • Sueyexin 2012-10-25 05:46
    关注

    这是一个很诡异的问题。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取消注册。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 maixpy训练模型,模型训练好了以后,开发板通电会报错,不知道是什么问题
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容