SharedPreference文件变化监听器OnSharedPreferenceChangeListener

来源:互联网 发布:网络机顶盒必装软件 编辑:程序博客网 时间:2024/06/05 10:07

原文:http://www.cnblogs.com/mgstone/p/5802384.html

问题再现

OnSharedPreferenceChangeListener是Android中SharedPreference文件发生变化的监听器。通常我们想要进行监听,会实现如下的代码。

protected void onCreate(Bundle savedInstanceState) {  PreferenceManager.getDefaultSharedPreferences(getApplicationContext())      .registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener() {      @Override      public void onSharedPreferenceChanged(          SharedPreferences sharedPreferences, String key) {          Log.i(LOGTAG, "testOnSharedPreferenceChangedWrong key =" + key);      }  });}这种写法看上去没有什么问题,而且很多时候开始几次onSharedPreferenceChanged方法也可以被调用。但是过一段时间(简单demo 不容易出现,但是使用DDMS中的gc会立刻导致接下来的问题),你会发现前面的方法突然不再被调用,进而影响到程序的处理。

原因剖析

简而言之,就是你注册的监听器被移除掉了。首先我们先了解一下registerOnSharedPreferenceChangeListener注册的实现。

private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =            new WeakHashMap<OnSharedPreferenceChangeListener, Object>();//some code goes herepublic void More ...registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {    synchronized(this) {      mListeners.put(listener, mContent);    }}

从上面的代码可以得知,一个OnSharedPreferenceChangeListener对象实际上是放到了一个WeakHashMap的容 器中,执行完示例中的onCreate方法,这个监听器对象很快就会成为垃圾回收的目标,由于放在WeakHashMap中作为key不会阻止垃圾回收, 所以当监听器对象被回收之后,这个监听器也会从mListeners中移除。所以就造成了onSharedPreferenceChanged不会被调 用。

关于WeakHashMap相关,请阅读 译文:理解Java中的弱引用 进而更多了解。

如何解决

改为对象成员变量(推荐)

将监听器作为Activity的一个成员变量,在Activity的onResume进行注册,在onPause时进行注销。推荐在这两个 Activity生命周期中进行处理,尤其是当SharedPreference值发生变化后,对Activity展示的UI进行处理操作的情况。这种方 法是最推荐的解决方案。

private OnSharedPreferenceChangeListener mListener = new OnSharedPreferenceChangeListener() {  @Override  public void onSharedPreferenceChanged(      SharedPreferences sharedPreferences, String key) {      Log.i(LOGTAG, "instance variable key=" + key);  }};@Overrideprotected void onResume() {  PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).registerOnSharedPreferenceChangeListener(mListener);  super.onResume();}@Overrideprotected void onPause() {  PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).unregisterOnSharedPreferenceChangeListener(mListener);  super.onPause();}(后略)
有着梦想,但改变不了世界, 只有坚持,让生活不再单调, 我不是我, 我还是我。
阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 德签申诉不成功怎么办 出国工作找对象怎么办 白色轿车有刮痕怎么办 办签证手机钱包怎么办 怎么办美国10年签证 我没有出生证明怎么办 去台湾探亲怎么办签证 漏接澳大利亚签证电话怎么办 冰岛游公证认证怎么办 莲蓬头开关坏了怎么办 淋浴莲蓬头坏了怎么办 手机ld密码忘掉怎么办 脊椎压迫神经头晕怎么办 脊椎疼导致头晕怎么办 脊椎疼引起头晕怎么办 去英国探亲签证怎么办 地税国税合并人员怎么办 机场服务员老了怎么办 在国外没有钱了怎么办 被劫持为人质怎么办 在印度签证过期怎么办 办签证被拒怎么办 澳洲留学生怎么办新加坡签证 韩国交换生签证怎么办 没有钱还贷款怎么办 英国主动退学后怎么办 英国留学被劝退怎么办 英国留学签证被拒怎么办 签证纸丢了怎么办 日本的探亲签证怎么办 成都去港澳怎么办签证 在北京怎么办泰国签证 法院判决不准离婚怎么办 再婚小孩上户口怎么办 被供应商起诉了怎么办 离婚案原告撤诉怎么办 离婚起诉不到场怎么办 判决书判了败诉怎么办 对执行裁定不服怎么办 贴吧尺寸超限怎么办 usbkey密码忘了怎么办