前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DataStore —— SharedPreferences 的替代者 ?

DataStore —— SharedPreferences 的替代者 ?

作者头像
路遥TM
发布2021-08-31 15:22:30
6000
发布2021-08-31 15:22:30
举报
文章被收录于专栏:路遥的专栏

瞎逛的时候发现了一个新东西,来和大家分享一下。

SharedPreferences 大家应该都用过,它的槽点很多,多到我专门写了一篇文章。

细数 SharedPreferences 的那些槽点 !

不过,官方吐槽,最为致命

  1. Synchronous API encourages StrictMode violations
  2. apply() and commit() have no mechanism of signalling errors
  3. apply() will block the UI thread on fsync()
  4. Not durable – it can returns state that is not yet persisted
  5. No consistency or transactional semantics
  6. Throws runtime exception on parsing errors
  7. Exposes mutable references to its internal state

我就不翻译了,可能会翻的不是很准确。以上吐槽来自 AndroidX 添加的新成员 DataStore 的类注释,地址如下:

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:datastore/datastore-core/src/main/kotlin/androidx/datastore/DataStore.kt

什么是 DataStore ?

那么,什么是 DataStore 呢?

DataStore provides a safe and durable way to store small amounts of data, such as preferences and application state. It does not support partial updates: if any field is modified, the whole object will be serialized and persisted to disk. If you want partial updates, consider the Room API (SQLite). DataStore provides ACID guarantees. It is thread-safe, and non-blocking. In particular, it addresses these design shortcomings of the SharedPreferences API。

这个我可以翻译一下。

DataStore 提供了一种存储轻量数据的安全稳定的方案,例如配置文件,应用状态等。它不支持局部更新:如果任何一个成员变量被修改了,整个对象都将被序列化并持久化到磁盘。对于局部修改,请考虑使用 Room 。

DataStore 保证原子性,一致性,隔离性,持久性。它是线程安全,且非阻塞的。尤其是,它解决了 SharedPreferences API 的设计缺陷。

好家伙,看起来这就是 SharedPreferences 的替代品了。

上代码

简单看一下代码实现。

DataStore 是一个接口。

代码语言:javascript
复制
interface DataStore<T> {
 
    val dataFlow: Flow<T>


    suspend fun updateData(transform: suspend (t: T) -> T): T

  
    interface Serializer<T> {

        fun readFrom(input: InputStream): T

        fun writeTo(t: T, output: OutputStream)

        val defaultValue: T
    }

    // TODO(b/151635324): Add initializers.
    // TODO(b/151635324): Add exception handlers.
    // TODO(b/151635324): Consider adding snapshot API.
}

没错,是基于 协程Flow 实现的。

  • dataFlow 是一个 Flow 对象
  • updateData() 用于更新对象
  • Serializer 接口,提供序列化和持久化能力

目前源码中仅仅提供了一个实现类:SingleProcessDataStore 。从名字就可以看出来,不支持多进程。看一下其中几个关键方法。

代码语言:javascript
复制
class SingleProcessDataStore<T>(
    private val produceFile: () -> File,
    private val serializer: DataStore.Serializer<T>,
    private val scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
) : DataStore<T> {
    ......
    private suspend fun readData(): T {
        // TODO(b/151635324): consider caching produceFile result.
        val file = produceFile()
        try {
            FileInputStream(file).use { stream ->
                return serializer.readFrom(stream)
            }
        } catch (ex: FileNotFoundException) {
            if (file.exists()) {
                throw ex
            }
            return serializer.defaultValue
        }
    }
    
    private fun writeData(newData: T) {
        // TODO(b/151635324): consider caching produceFile result.
        val file = produceFile()
        file.mkdirs()
        val scratchFile = File(file.absolutePath + SCRATCH_SUFFIX)
        try {
            FileOutputStream(scratchFile).use { stream ->
                serializer.writeTo(newData, stream)
                stream.fd.sync()
                // TODO(b/151635324): fsync the directory, otherwise a badly timed crash could
                //  result in reverting to a przuihouevious state.
            }
            scratchFile.renameTo(file)
        } catch (ex: IOException) {
            if (scratchFile.exists()) {
                scratchFile.delete()
            }
            throw ex
        }
    }
    ......
}

readData()writeData() 实际都是在读写文件。

具体用法详见官方写的单元测试 SingleProcessDataStoreTest,地址如下:

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:datastore/datastore-core/src/test/kotlin/androidx/datastore/SingleProcessDataStoreTest.kt

最后

到目前为止,DataStore 仍在开发中,并没有发布过任何可用的版本 ,现在并不足以替代 SharedPreferences 。按 Google 的尿性,哪天流产了其实也不足为奇。你可以在 androidx-master-dev 中持续关注。

不过两个问题是可以确定的。

第一,Google 自己也快看不下去 SharedPreferences 了。

第二,越来越多的新特性都是基于 Kotlin 实现的了,甚至只对 Kotlin 提供支持,大有 Kotlin First 到 Kotlin Only 的趋势。

所以,还没有学习 Kotlin 的同学们,抓紧上车吧!


今天的文章就到这里了,我是一直坚持原创的秉心说,更多最新 Android 动态,扫码关注我的公众号吧 !

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 路遥TM 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 DataStore ?
  • 上代码
  • 最后
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档