1. 认识 DataStore:用途、两种实现与适用场景

Jetpack DataStore 是 Android 官方推出的轻量级本地数据存储解决方案,旨在替代 SharedPreferences,提供异步、一致且类型安全的键值存储与结构化数据持久化能力。它基于 Kotlin 协程和 Flow(数据流)构建,天然支持反应式编程与生命周期安全。

1.1 核心用途

  • 持久化应用设置与偏好:如主题、语言、通知开关等轻度用户配置。
  • 小型结构化数据缓存:如最近使用的项目列表、登录状态标志。
  • 单进程内数据共享:同一 App 内多个组件通过 Flow 观察数据变化,实现实时同步。
  • 替代 SharedPreferences 线程安全与异常问题:DataStore 确保主线程安全,并支持 try-catch 处理序列化/反序列化异常。

1.2 原理概述

DataStore 以文件形式将数据持久化到设备内部存储。读取时返回 Flow<T>,数据变更时会自动发射新值;写入操作通过挂起函数 updateData() 或 edit() 实现事务性修改。整个读写过程由协程调度,避免阻塞主线程。

1.3 两种实现对比

特性Preferences DataStoreProto DataStore
数据结构键-值对(Key-Value),值类型固定(Int、String、Boolean、Float、Double、StringSet 等)基于 Protocol Buffers(protobuf)定义的结构化对象,支持嵌套、枚举、自定义类型
类型安全弱类型,需在存取时手动转换强类型,编译期生成 Java/Kotlin 类
Schema 演进无 schema,字段增删需手动处理默认值支持向后兼容,proto 文件定义字段编号,可安全新增/废弃字段
依赖体积小,仅需 datastore-preferences较大,需引入 datastore 和 protobuf 插件
适用场景简单设置项、开关、计数器复杂配置对象、网络缓存模型、数据迁移
读写性能写入快(全量替换),但读取全部数据后过滤写入稍慢(序列化成本),读取按需反序列化字段
选择建议:Preferences DataStore 适合 少于 20 个键 的纯设置场景;Proto DataStore 适合 结构化、版本可演进 的数据模型。

1.4 适用场景决策流程

DataStore 实现选择流程图 需要持久化数据? 数据结构 是否固定且简单? 是(键值对) Preferences DataStore • 键值对存储 • 异步 Flow • 轻量快速 否(复杂/需演进) Proto DataStore • 类型安全 • Schema 演进 • 自定义对象 常见误区提醒 Preferences DataStore 适合简单设置,切勿存储结构化业务数据 Proto DataStore 多进程需额外处理,默认仅支持单进程

1.5 依赖引入与基础配置

在 build.gradle.kts(模块级)添加对应依赖:

// Preferences DataStore
implementation("androidx.datastore:datastore-preferences:1.1.1")

// Proto DataStore(需要额外配置 protobuf 插件)
implementation("androidx.datastore:datastore:1.1.1")
// 还需要在 build.gradle.kts 中配置 protobuf 插件和定义 .proto 文件
⚠ 版本兼容提示:DataStore 1.1.x 要求 Kotlin 1.8+ 以及 compileSdk 33+。若使用更低版本,请查阅官方迁移指南。

1.6 常见错误与稳定性优化

  • 在非协程作用域调用写入方法:必须处于协程上下文中,否则编译报错。
  • 文件损坏导致读取异常:DataStore 内部使用事务日志,但极端情况仍可抛出 CorruptionException,建议在外层 catch 后重建。
  • 跨进程共享不可靠:DataStore 本身不支持多进程并发,需要跨进程应在 ContentProvider 或自定义 Service 中封装。
  • 高频写操作合并:DataStore 会合并 5 秒内的连续写入为一次磁盘操作,避免频繁 I/O 抖动。
  • 使用 dataStore.data 的 collect 时注意取消:配合 repeatOnLifecycle 或 flowWithLifecycle 防止生命周期泄露。
性能要点:首次读 DataStore 时会从文件加载全部数据到内存缓存,后续读取仅返回缓存;写入时先更新缓存再异步写回文件。保持每个 DataStore 实例管理的数据量在 100KB 以内可达到最佳性能。