0Pricing
Android Academy · 课时

DataStore 与 SharedPreferences

了解 DataStore 为什么是现代选择

DataStore 与 SharedPreferences 是 CoddyKit 上的免费 Android Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 4 节课。

存储少量设置

几乎每个应用都需要记住一些少量数据:深色模式开关、上次使用的标签页、用户名等。这些属于键值偏好设置,而不是大型关系型数据。

多年来,Android 一直使用 SharedPreferences 完成这项工作。如今推荐的解决方案是 DataStore。

什么是 SharedPreferences

SharedPreferences 是一种由 XML 支持的简单键值存储。您可以获取编辑器、写入值,然后提交这些值。

  • 易于使用
  • 内置于框架中
  • 同步 API 可能阻塞界面线程
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
prefs.edit().putBoolean("dark_mode", true).apply()
val dark = prefs.getBoolean("dark_mode", false)

SharedPreferences 的问题

SharedPreferences 存在一些实际缺陷:

  • getX() 读取操作可能阻塞调用线程(通常是主线程)
  • commit() 会同步执行磁盘 I/O
  • 没有内置的错误通知机制
  • API 既不具备类型安全性,也不是响应式的

引入 DataStore

DataStore 是基于 Kotlin 协程和 Flow 构建的现代替代方案。它会在主线程之外执行所有磁盘操作,并将数据公开为可观察流。

DataStore 有两种形式:Preferences DataStore(键值数据)和 Proto DataStore(类型化对象)。

从设计上支持异步

DataStore 永远不会阻塞界面。读取操作通过您收集的 Flow 提供,写入操作则是从协程中调用的 suspend 函数。

这意味着即使在主线程上读取和写入设置也是安全的,因为繁重的工作会在后台调度器上执行。

val darkMode: Flow<Boolean> = dataStore.data
    .map { prefs -> prefs[DARK_MODE_KEY] ?: false }

响应式更新

由于 DataStore 公开的是 Flow,因此值发生变化时,界面会自动更新。使用 SharedPreferences 时,您必须注册一个繁琐的变更监听器。

在 Jetpack Compose 中,您只需对流调用 collectAsState(),屏幕就会在每次更新时重新组合。

事务性与一致性

DataStore 的写入操作具有事务性。更新要么完全成功,要么完全失败,因此您永远不会读取到只写入了一部分的值。

此外,在同一进程中进行多次读取和写入时,它也能保证数据一致性。

错误处理

SharedPreferences 会悄悄吞掉 I/O 问题。DataStore 会将问题暴露出来:读取操作可能通过流发出 IOException,您可以使用 catch 捕获并进行恢复。

val settings: Flow<Settings> = dataStore.data
    .catch { e ->
        if (e is IOException) emit(emptyPreferences())
        else throw e
    }
    .map { /* map to your model */ }

DataStore 不适用的情况

DataStore 适用于少量或中等规模的键值数据或类型化数据。它不是数据库。

  • 大型数据集、查询、关系:使用 Room
  • 文件、图片、媒体:使用文件系统
  • 少量设置:使用 DataStore

添加依赖

要使用偏好设置 DataStore,请将相应构件添加到模块的 Gradle 文件中。Proto DataStore 使用单独的构件。

dependencies {
    implementation("androidx.datastore:datastore-preferences:1.1.1")
}

从 SharedPreferences 迁移

您不必一次性重写所有内容。DataStore 提供了 SharedPreferencesMigration,可在首次读取时自动迁移现有值。

val Context.dataStore by preferencesDataStore(
    name = "settings",
    produceMigrations = { context ->
        listOf(SharedPreferencesMigration(context, "settings"))
    }
)

快速检查

请检验您对为何首选 DataStore 的理解。

回顾

您已经了解了为何 DataStore 是键值设置的现代选择:

  • SharedPreferences 可能阻塞主线程,并且不是响应式的
  • DataStore 使用协程和 Flow 实现安全的异步访问
  • 写入具有事务性,并配有适当的错误处理
  • 有两种形式:偏好设置和 Proto

接下来,您将在实践中使用 preferencesDataStore 委托。

常见问题解答

「DataStore 与 SharedPreferences」课时是免费的吗?

是的 — 「DataStore 与 SharedPreferences」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 4 节课。

「DataStore 与 SharedPreferences」这节课中我会学到什么?

了解 DataStore 为什么是现代选择 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Android Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「DataStore 与 SharedPreferences」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Android Academy 课中编写并运行代码吗?

能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. DataStore 与 SharedPreferences
  2. Preferences DataStore
  3. 读取和写入设置
  4. Proto DataStore
← 返回 Android Academy