android-SharedPreferences.onSharedPreferenceChangeListener不能一直被调用

问题描述

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);
        }
    });

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

解决方案

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

解决方案二:

对我来说就是每次创建新的实例,恢复activity
所以在activity中保持监听器的参数怎么样

OnSharedPreferenceChangeListener myPrefListner = new OnSharedPreferenceChangeListener(){
      public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
      }
}

在你的onResume和onPause

@Override
protected void onResume() {
    super.onResume();
    getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(myPrefListner);
}

@Override
protected void onPause() {
    super.onPause();
    getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(myPrefListner);

}

除了我们维护一个参数以为,这都和你想要的非常类似。

时间: 2024-10-27 17:54:02

android-SharedPreferences.onSharedPreferenceChangeListener不能一直被调用的相关文章

Android SharedPreferences四种操作模式使用详解

Android  SharedPreferences详解 获取SharedPreferences的两种方式: 1 调用Context对象的getSharedPreferences()方法 2 调用Activity对象的getPreferences()方法 两种方式的区别: 调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享. 调用Activity对象的getPreferences()方法获得的Sh

Android SharedPreferences实现数据存储功能

除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,不同于文件的存储方式,SharedPreferences是使用键值对(key-value)数据的方式来存储数据的.而且SharedPreferences还支持多种不同的数据类型存储,因此,使用SharedPreferences来进行数据持久化要比使用文件方便很多,下面我们就来看一下它的具体用法吧. 如何将数据存储到SharedPreferences中 要想使用SharedPreferences来存储数据,首先

Android编程之Activity中onDestroy()调用分析_Android

本文分析了Android编程之Activity中onDestroy()调用方法.分享给大家供大家参考,具体如下: 刚刚一个BUG让我发现,如果 activity 实现了一个回调接口,然后使用 this 设置给需要回调接口的方法,这种应用场景比较常见,最常见的就是实现 onClickListener 接口,然后 findViewById().setOnClickListenr(this) 如果,这个回调接口设置到了一个静态对象(单例模式),当 activity finish() 的时候(按返回键,

android broadCastReceive动态注册后必须调用注销吗?

问题描述 android broadCastReceive动态注册后必须调用注销吗? android broadCastReceive动态注册后必须调用注销吗?静态注册就算关闭程序,还会接收广播吗,静态注册能注销吗? 解决方案 最近在学广播接受者.印象中动态注册了不一定要注销的(不会直接导致报错),但是会一直占用资源,所以不用了建议注销掉.刚刚上网查了查:动态注册和静态注册一个BroadcastReceiver的区别:动态注册较静态注册灵活.实验证明:当静态注册一个BroadcastReceiv

android 中 如何通过java代码调用style样式

问题描述 android 中 如何通过java代码调用style样式 平时做开发,通常style样式直接在xml布局文件中直接调用,如果我想直接在java代码中通过动态加载来设置,是否可以?通过查阅资料,很多说不可以,解决方式是把style中的逐条信息加载设置,还有其他途径可以设置吗? 解决方案 无其他方式无其他方式无其他方式 解决方案二: 我们之前的一个项目也尝试过在java里面动态加载style,最后也放弃了,这个确实做不到,楼主想想其它方法吧 解决方案三: 多谢,各位,目前我没有发现动态加

android开发,华为P7,调用系统发短信,传递2个电话号码会发生错误,其他个数不会

问题描述 android开发,华为P7,调用系统发短信,传递2个电话号码会发生错误,其他个数不会 传递两个号码,比如"12222222223;45555555556",显示出来的是"2222222223,45555555556,1",第一个电话号码被分割了. 有人遇到吗? 解决方案 http://blog.csdn.net/coolszy/article/details/7882827 解决方案二: 你把源码贴出来给我看看呀 解决方案三: Uri smsToUri

解析android framework下利用app_process来调用java写的命令及示例

解析android framework下利用app_process来调用java写的命令及示例          在android SDK的framework/base/cmds目录下了,有不少目录,这些目的最终都是build出一个bin文件,再存放到/system/bin目录下,对于C/CPP写的命令,我们还是比较好理解的,都有一个main函数作为入口,但是在cmds目录下还有一些原生代码是java的,比如input.settings,那么这种类型的命令是怎么实现的呢?       笔者研习了

android:自定义button继承自button, 调用setTextcolor无效

问题描述 android:自定义button继承自button, 调用setTextcolor无效 现在有个需求是当button失去焦点时, text文字的颜色会变化. 1. 在attrs.xml中我声明了两个属性normalColor和selectedColor, 2. 然后在自定义button类中: TypedArray typeArray = mContext.obtainStyledAttributes(attrs, R.styleable.LtButton); if (null !=

在Android系统中Service的远程调用

在Android系统中Service的远程调用 http://liangruijun.blog.51cto.com/3061169/653344