持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情
接下来会对
Preference Library官方库进行一个系列讲解,本篇文章是Preference Library系列的第四篇,主要是介绍Preference Library如何实现设置项配置变化监听。
历史文章
练气篇:设置界面的开发利器Preference Library,了解一下~
筑基篇:设置界面的开发利器Preference Library,了解一下~
金丹篇:设置界面的开发利器Preference Library,了解一下~
元婴篇:设置界面的开发利器Preference Library,了解一下~
Preference Library实现设置项配置变化监听有两种方式:
-
Preference.OnPreferenceChangeListener -
SharedPreferences.OnSharedPreferenceChangeListener
具体的区别如下(来自官方):
在讲解这四大区别之前,我们先看下这两种方式对应的代码逻辑是如何实现的:
实现方式
1. Preference.OnPreferenceChangeListener
调用方法setOnPreferenceChangeListener()
findPreference<Preference>("develop")?.let {
it.setOnPreferenceChangeListener { preference, newValue ->
return@setOnPreferenceChangeListener true
}
}
2. SharedPreferences.OnSharedPreferenceChangeListener
val listener: SharedPreferences.OnSharedPreferenceChangeListener =
SharedPreferences.OnSharedPreferenceChangeListener {
}
preferenceManager.sharedPreferences?.registerOnSharedPreferenceChangeListener(listener)
这个地方有个非值得注意的地方:
通过
registerOnSharedPreferenceChangeListener()注册的监听器是保存到SharedPreferenceImpl的弱引用集合中的:
private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners =
new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
@Override
public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
synchronized(mLock) {
mListeners.put(listener, CONTENT);
}
}
就是因为写入到的一个是弱引用集合 ,所以一旦发生GC这个对象就直接回收了,我们的监听也就没啥作用的了,所以我们需要在外部持有一个强引用才行。
接下来我们就分别讲讲区别。
两种监听变化的区别
1. 应用范围不同
-
Preference.OnPreferenceChangeListener是为了单独设置给某个Preference设置项使用的,不和其他设置项共享使用; -
SharedPreferences.OnSharedPreferenceChangeListener是设置给所有的配置项使用的,全局共享;
2. 监听范围不同
-
Preference.OnPreferenceChangeListener只要值发生了变化就会回调,包括了这个变化后的值和之前保存的值相同,监听范围更广; -
SharedPreferences.OnSharedPreferenceChangeListener只有在值发生了变化之后才进行调用,也就是说值不发生变化,就不会回调该对象;
3. 回调时机不同
-
Preference.OnPreferenceChangeListener是在设置项的配置值写入到本地之前进行调用; -
SharedPreferences.OnSharedPreferenceChangeListener是在设置项的配置值写入到本地之后进行调用;
4. 作用范围不同
-
Preference.OnPreferenceChangeListener不论是你使用默认SharedPreference存储还是其他自定义存储库,只要值发生变化,就可以收到这个回调; -
SharedPreferences.OnSharedPreferenceChangeListener从其名字就可以看出来,专门用户官方SharedPreference监听使用的,如果你自定义存储,那这个回调就无效了;
5. 响应范围不同
-
Preference.OnPreferenceChangeListener只有因Preference Library这个库引发的设置项配置变化才能收到回调,也就是说,如果在其他和Preference Library库实现无关的界面上(比如应用主界面等等),你手动获取SharedPreference去修改这个值,那这个监听将是无效的; -
SharedPreferences.OnSharedPreferenceChangeListener设置的SharedPreference监听是全局的,也就是说,只要在这个应用的任何地方触发了配置值的更改,那就可以收到回调,可以说是相当的强大。
但这样就会引入一个问题,如果你已经不再设置界面了,你为啥还要监听配置值的变化,一旦设置界面销毁了你还在监听变化,
这不是很容易引发内存泄漏吗?(创建的OnPreferenceChangeListener会持有外部类Fragment或Activity的引用),所以我们需要管理监听器的注册和反注册
代码如下:
val listener: SharedPreferences.OnSharedPreferenceChangeListener =
SharedPreferences.OnSharedPreferenceChangeListener {
}
override fun onResume() {
super.onResume()
preferenceManager.sharedPreferences?.registerOnSharedPreferenceChangeListener(listener)
}
override fun onPause() {
super.onPause()
preferenceManager.sharedPreferences?.registerOnSharedPreferenceChangeListener(listener)
}
总结
本篇文章主要是讲解了如何实现Preference Library中设置项配置值变化的监听,主要是有两种方式并分析了区别,希望能给你带来帮助。