持续创作,加快生长!这是我参与「日新计划 10 月更文挑战」的第18天,点击检查活动详情

接下来会对Preference Library官方库进行一个系列解说,本篇文章是Preference Library系列的第四篇,主要是介绍Preference Library怎么完成设置项装备改变监听。

历史文章

练气篇:设置界面的开发利器Preference Library,了解一下~

筑基篇:设置界面的开发利器Preference Library,了解一下~

金丹篇:设置界面的开发利器Preference Library,了解一下~

元婴篇:设置界面的开发利器Preference Library,了解一下~

Preference Library完成设置项装备改变监听有两种办法:

  1. Preference.OnPreferenceChangeListener

  2. SharedPreferences.OnSharedPreferenceChangeListener

具体的区别如下(来自官方):

炼虚篇:设置界面的开发利器Preference Library,了解一下~

在解说这四大区别之前,咱们先看下这两种办法对应的代码逻辑是怎么完成的:

完成办法

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会持有外部类FragmentActivity的引证),所以咱们需求管理监听器的注册和反注册

代码如下:

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中设置项装备值改变的监听,主要是有两种办法并剖析了区别,希望能给你带来帮助。