Android中SharedPreferences的onSharedPreferenceChanged未触发问题求助
嘿,我来帮你搞定这个监听器没反应的坑!我之前踩过类似的雷,咱们从几个最常见的原因入手排查:
监听器被垃圾回收(GC)干掉了
这是最容易踩的坑!你用匿名内部类注册监听器,要是没有一个强引用变量持有它,系统很容易把这个监听器回收掉,导致后续的修改触发不了回调。
解决办法很简单,把监听器改成Activity的成员变量:// 在Activity类里定义成员变量 private SharedPreferences mPrefs; private SharedPreferences.OnSharedPreferenceChangeListener mPrefListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this); // 初始化监听器并注册 mPrefListener = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { getData(); } }; mPrefs.registerOnSharedPreferenceChangeListener(mPrefListener); } // 记得在Activity销毁时注销监听器,避免内存泄漏 @Override protected void onDestroy() { super.onDestroy(); if (mPrefs != null && mPrefListener != null) { mPrefs.unregisterOnSharedPreferenceChangeListener(mPrefListener); } }SharedPreferences的修改没提交
要确保另一个Activity修改SharedPreferences时,调用了apply()或者commit()来提交修改,不然数据根本没写入,自然不会触发回调。正确的修改代码应该是这样:// 另一个Activity中保存对象的代码 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor editor = prefs.edit(); Gson gson = new Gson(); String json = gson.toJson(yourTargetObject); // 替换成你的对象 editor.putString("your_object_key", json); // 确保Key和监听时一致 editor.apply(); // 推荐用apply(),异步提交不阻塞主线程监听的Key不匹配
检查你在getData()里解析时用的Key,和另一个Activity保存时用的Key是不是完全一致——大小写、拼写都不能错!比如存的时候用"user_info",取的时候写成"User_Info",就会导致解析不到数据,看起来像回调没触发,但其实是Key不匹配。目标Activity被系统回收
如果你的监听Activity已经被后台系统回收了,那肯定收不到回调。其实SharedPreferences更适合存储轻量的配置数据,跨Activity传递对象并不是它的最优选择。如果场景需要实时跨页面通信,你可以考虑用这些方案:- 用Intent传递
Parcelable/Serializable序列化对象 - 借助ViewModel+LiveData实现跨页面数据监听
- 用EventBus这类事件总线框架
- 用Intent传递
如果以上都排查过还是没解决,可以在注册监听器后手动调用一次getData()初始化数据,同时在另一个Activity提交修改后打个Log,确认数据是否真的写入了SharedPreferences,这样能快速定位问题。
内容的提问来源于stack exchange,提问作者BryceSoker

