DataStore —— SharedPreferences 的替代者 ?

简介: DataStore —— SharedPreferences 的替代者 ?

什么是 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 是一个接口。

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 。从名字就可以看出来,不支持多进程。看一下其中几个关键方法。


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 的同学们,抓紧上车吧!



相关文章
|
5月前
|
存储 API 文件存储
47. 【Android教程】SharedPreferences 存储
47. 【Android教程】SharedPreferences 存储
60 2
|
3月前
|
存储 安全 API
Android经典实战之存储方案对比:SharedPreferences vs MMKV vs DataStore
本文介绍了 Android 开发中常用的键值对存储方案,包括 SharedPreferences、MMKV 和 DataStore,并对比了它们在性能、并发处理、易用性和稳定性上的特点。通过实际代码示例,帮助开发者根据项目需求选择最适合的存储方案,提升应用性能和用户体验。
82 1
|
存储 安全 Java
Android DataStore:安全存储和轻松管理数据
Android DataStore:安全存储和轻松管理数据
|
6月前
|
存储 XML 文件存储
Android数据存储:什么是SharedPreferences?它有什么用途?
Android数据存储:什么是SharedPreferences?它有什么用途?
257 0
|
存储 XML 安全
数据存储之SharedPreferences
数据存储之SharedPreferences
118 0
|
API Android开发
安卓开发之使用SharedPreferences保存键值对数据
如果您有想要保存的相对较小键值对集合,则应使用 SharedPreferences API。SharedPreferences 对象指向包含键值对的文件,并提供读写这些键值对的简单方法。每个 SharedPreferences 文件均由框架进行管理,可以是私有文件,也可以是共享文件。
198 1
安卓开发之使用SharedPreferences保存键值对数据
|
存储
1-SII--SharedPreferences完美封装
零、前言 以前我的SharedPreferences封装类根据不同类型getXXX,setXXX分好多情况。现在回过头看看,咱也是玩过泛型的。 突然灵光一闪,"少年,看你骨骼惊奇,泛型了解一下吗。
1095 0
DHL
|
存储 JSON Ubuntu
[Google]再见SharedPreferences拥抱DataStore (二)
今天这篇文章主要来介绍 Proto DataStore,Proto DataStore 通过 protocol buffers 将对象序列化存储在本地,所以首先需要安装 Protobuf 编译 proto 文件,Protobuf 编译大致分为 Gradle 插件编译和命令行编译
DHL
310 0
[Google]再见SharedPreferences拥抱DataStore (二)
|
存储 Java API
Android 数据存储(二)-SP VS DataStore VS MMKV
一、SharedPreferences 不同于文件的存储方式,如果要保存的键值集合相对较小,则应使用SharedReferences API。SharedReferences对象指向一个包含键值对的文件,并提供简单的读写方法。 本文从SharedReferences开始逐步引入Preference、MMKV。
1230 0
Android 数据存储(二)-SP VS DataStore VS MMKV
DHL
|
存储 缓存 安全
[Google] 再见 SharedPreferences 拥抱 Jetpack DataStore
Google 新增加了一个新 Jetpack 的成员 DataStore,主要用来替换 SharedPreferences, DataStore 应该是开发者期待已久的库,DataStore 是基于 Flow 实现的,一种新的数据存储方案,它提供了两种实现方式
DHL
325 0
[Google] 再见 SharedPreferences 拥抱 Jetpack DataStore