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 ...
随机推荐
- 包管理和环境管理软件Anaconda
可以用于配置linux下得虚拟环境,该软件可以针对不同服务配置不同的运行环境,方便包管理与环境管理
- 〖Android〗dropbear一些操作命令备忘
相关命令行: # 启动dropbear后台运行 /data/local/tmp/dropbear \ -A -N android -I -C -G -p \ -R /data/local/tmp/au ...
- 分享自己针对Automation做的两个成熟的框架(QTP 和Selenium)
自己在google code中开源了自己一直以来做的两个自动化的框架,一个是针对QTP的一个是针对Selenium的,显而易见,一个是商业的UI automation工具,一个是开源的自动化工具. 只 ...
- Xamarin.Android服务的实现
一.服务的生命周期 服务与活动一样,在它的整个生命周期中存在着一些事件,下图可以很好解释整个过程以及涉及到的方法: 在真实的使用中,Service来还包含一个OnBind方法,并且必须要使用该方法,但 ...
- excel 如何快速实现绝对引用
当函数输入完成并框选数据区域后,变成如上效果时,按“F4键”即可
- Ubuntu18.04和OpenWrt 18.06.0 下使用aria2和BaiduExport处理百度盘下载
Ubuntu下没有可用的百度盘客户端, 下载大文件如果通过浏览器就会特别不可靠. 可以使用Chrome插件 BaiduExport 得到下载链接和参数后, 通过aria2进行下载. Aria2安装 直 ...
- 用Redis的zset防御Session Flood
zset (Sorted Set)是set的升级版本, 在set的基础上增加了一个顺序(或者权重)值属性, 属性在添加修改元素时候可以指定. 每次指定后zset会自动重新按新的值调整顺序. 可以理解为 ...
- Region使用全解
代码地址如下:http://www.demodashi.com/demo/14799.html 前言 Region,即为区域,它表示的是canvas图层上的某一块封闭的区域.很多时候,我们会利用Reg ...
- 微信小程序解决方案合集
微信小程序解决方案合集:http://www.wxapp-union.com/special/solution.html 跳坑系列:http://www.wxapp-union.com/forum.p ...
- Emacs中Golang的设置
欲善其事,先利其器.下面记录一些使用Emacs24做golang开发中的一些有用设置,备忘用. 一,golang中的代码跳转 emacs24的go-mode中默认用godef-describe,god ...