SharePreference 注册 registerOnSharedPreferenceChangeListener 无法回调的问题
以前一直没有用过 registerOnSharedPreferenceChangeListener 回调方法,今天用到了,就设置了下,结果发现不起作用,因为一直没有回调。
代码:
mSp = this.getSharedPreferences(HuaweiPushReceiver.SP_Name, MODE_PRIVATE);
mSp.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
String token = sharedPreferences.getString(HuaweiPushReceiver.SP_KEY, null);
tv.setText("sp token:" + token);
Log.d(TAG, "sp token:" + token);
}
});
然后就搜索和看源码,已经有人提出了这个问题及解决办法,因为 SharedPreferences 的实现类 SharedPreferencesImpl 中对于观察者模式的储存使用的是 WeakHashMap ,所以当储存的 key 没有使用的时候就会回收掉,而上面的代码中使用的是匿名内部类,所以就容易被 GC 掉。
源码:
private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =
new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
SharedPreferencesImpl(File file, int mode) {
mFile = file;
mBackupFile = makeBackupFile(file);
mMode = mode;
mLoaded = false;
mMap = null;
startLoadFromDisk();
}
...
public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
synchronized(this) {
mListeners.put(listener, mContent);
}
}
解决办法:
不使用匿名内部类,同时在 onStart() 中注册,在 onStop() 中取消注册。
SharedPreferences mSp;
SharedPreferences.OnSharedPreferenceChangeListener mListener = new SharedPreferences
.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
String token = sharedPreferences.getString(HuaweiPushReceiver.SP_KEY, null);
tv.setText("sp token:" + token);
Log.d(TAG, "sp token:" + token);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
mSp = this.getSharedPreferences(HuaweiPushReceiver.SP_Name, MODE_PRIVATE);
}
...
}
@Override
protected void onStart() {
super.onStart();
mClient.connect();
mSp.registerOnSharedPreferenceChangeListener(mListener);
}
@Override
protected void onStop() {
mSp.unregisterOnSharedPreferenceChangeListener(mListener);
super.onStop();
}
SharePreference 注册 registerOnSharedPreferenceChangeListener 无法回调的问题的更多相关文章
- ZeroMQ接口函数之 :zmq_socket_monitor - 注册一个监控回调函数
ZeroMQ 官方地址 :http://api.zeromq.org/4-2:zmq-socket-monitor zmq_socket_monitor(3) ØMQ Manual - ØMQ/4.1 ...
- (转)Unity3d通过Action注册事件,回调方法
http://www.cnblogs.com/jisi5789/archive/2013/04/22/3036589.html using UnityEngine; namespace Liulala ...
- OpenGL的GLUT注册回调函数[转]
OpenGL的注册回调函数 void glutDisplayFunc(void (*func)(void) ); 为当前窗口设置显示回调函数 void glutOverlayDisplayFunc(v ...
- cocos2d-x 2.2.0 如何在lua中注册回调函数给C++
cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件.翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做.值得吐 ...
- android aidl通信 RemoteCallbackList客户端注册回调
RemoteCallbackList 声明 public class RemoteCallbackList<E extends IInterface> 情况 在AIDL中客户端向服务端注册 ...
- 计算机基础,Python - 回调函数,使用装饰器注册回调函数
1. 参考: https://en.wikipedia.org/wiki/Callback_(computer_programming) https://developer.mozilla.org/e ...
- 驱动开发:内核枚举Registry注册表回调
在笔者上一篇文章<驱动开发:内核枚举LoadImage映像回调>中LyShark教大家实现了枚举系统回调中的LoadImage通知消息,本章将实现对Registry注册表通知消息的枚举,与 ...
- 驱动开发:内核监控Register注册表回调
在笔者前一篇文章<驱动开发:内核枚举Registry注册表回调>中实现了对注册表的枚举,本章将实现对注册表的监控,不同于32位系统在64位系统中,微软为我们提供了两个针对注册表的专用内核监 ...
- Sipdroid实现SIP(一): 注册
目录 注册: 预注册获取长号和用户注册 预注册返回长号 周期性用户注册 Receiver类概述 SipdroidEngine类概述 Sipdroid类中的用户注册: 注册代理和注册事务 注册代理类Re ...
随机推荐
- Dwr 框架简单实例
Dwr 是一个 Java 开源库,帮助你实现Ajax网站. 它可以让你在浏览器中的Javascript代码调用Web服务器上的Java,就像在Java代码就在浏览器中一样. Dwr 主要包括两部分: ...
- SQL Server connect to MySQL SQL Server通过LinkServer访问MySQL数据库,并操作mysql数据库代码
SQL Server 中需要访问MySQL的数据,可以通过调用MySQL的ODBC驱动,在SQL Server中添加LinkServer的方式实现. 1.从MySQL网站下载最新的MySQL ODBC ...
- Dlib机器学习指南图翻译
原图地址 http://dlib.net/ml_guide.svg 翻译的文件 http://files.cnblogs.com/files/oloroso/ml_guide.zip
- spring aop实现日志收集
概述 使用spring aop 来实现日志的统一收集功能 详细 代码下载:http://www.demodashi.com/demo/10185.html 使用spring aop 来实现日志的统一收 ...
- 调用布局View的performClick()方法
修改之前的xml片段. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/an ...
- Nosql数据库的四大分类及分布式数据库CAP原理
1. Nosql数据库的四大分类 2. 分布式数据库CAP原理 2.1 关系型数据库事务遵循的ACID规则 首先了解传统关系型数据库事务遵循的ACID规则: 原子性(Atomicity):事务里的所有 ...
- java中enum的应用
package com.demo; public enum TestEnum { A("hello"), B("world"); private String ...
- golang 学习笔记 ---数组/字符串/切片
数组 数组是一个由固定长度的特定类型元素组成的序列,一个数组可以由零个或多个元素组成.数组的长度是数组类型的组成部分.因为数组的长度是数组类型的一个部分,不同长度或不同类型的数据组成的数组都是不同的类 ...
- win7 32 安装mongoDB遇到的问题
net start MongoDB报错:发生服务特定错误: 100. 直接进入db文件夹,先删除 mongod.lock 文件,然后重新启动服务即可:要是还不行,就继续删 storage.bson文件 ...
- Easyui combobox 始终选择第一个的问题
//必须指定 id 和 text $('#contact_city').combobox({ valueField:'id', textField:'text', });