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

223 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

接下来会对Preference Library官方库进行一个系列讲解,本篇文章是Preference Library系列的第五篇,主要是介绍Preference Library如何自定义存储逻辑。

历史文章

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

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

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

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

为啥需要自定义存储?

Preference Library默认的存储是使用SharedPreferencec实现,但是总所周知,SharedPreferencec有几个缺点容易导致ANR,比如:

  1. 初始化时全量将本地xml中的数据读取到内存,未读取成功前会发生阻塞,且占用内存大小;

  2. 当界面走到比如stop生命周期,会阻塞等待数据写入本地完毕,这个也可能会导致ANR;

上面只是说了两点,所以不太适合某些场景下的存储,而官方提供了更为强大的DataStore、腾讯提供了MMKV等等。

其实官方还说了其他可能用到自定义存储的逻辑:

image.png

所以Preference Library提供了自定义的存储接口PreferenceDataStore,方便我们将配置数据使用其他存储库写入到本地,非常的方便。

自定义PreferenceDataStore

继承PreferenceDataStore

class CustomDataStore : PreferenceDataStore() {
    override fun putString(key: String, value: String?) {
        //自定义存储值的操作
    }

    override fun getString(key: String, defValue: String?): String {
        //自定义获取值的操作
        return ""
    }
}

PreferenceDataStore有很多个读写类型方法,这里只是单独拿出了String类型举例。

接下来就得将我们自定义的存储对象CustomDataStore设置一下才能生效,这里提供了两种方式:

  1. CustomDataStore应用于单个Prefereence的读写
findPreference<Preference>("develop")?.let {
    it.preferenceDataStore = CustomDataStore()
}
  1. CustomDataStore应用于全体Prefereence的读写
val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = CustomDataStore()

PreferenceManager是全局的,所以设置了preferenceDataStore就可以应用到全局,这点从我们之前分析到的源码就可以看到:

image.png

注意事项

  1. 一旦你决定了自定义存储,那么对于你需要操作的数据类型的读写你都要重写PreferenceDataStore对应的类型读写方法,否则就会导致异常:
image.png
  1. 设置存储区需要有个特定的时机:

image.png

上面是官方的说法。这个有什么用呢,比如当初你使用SharedPreference后想要换个存储工具比如DataStoreMMKV,那就得将之前的值迁移到另外的库中,那么在Preference附加到整体层次结构之前设置自定义存储去,系统就会传播当前设置项的配置值,这样就方便使用其他的框架将该配置值迁移到其他框架中存储。

总结

本篇文章主要是介绍了如何在Prefeernce Library中实现自定义存储,以及应用存储的两种方式:单个和全局,希望本篇文章能对你有所帮助。