3. 项目环境搭建:添加DataStore依赖、配置Gradle版本、迁移前备份策略
项目环境搭建是实施 DataStore 改造的第一步,也是最容易被忽略的环节。错误的依赖声明或 Gradle 版本不匹配会导致编译失败;缺失迁移备份策略则可能在生产环境中丢失用户数据。本章从依赖引入、版本锁定、备份三个维度给出可落地的操作方案。
3.1 添加 DataStore 依赖
DataStore 官方提供两个变体:Preferences DataStore(轻量键值对)和 Proto DataStore(带 Schema 的类型安全存储)。根据项目需求选择其一,或同时引入。
推荐: 新项目直接使用 Proto DataStore 可获得强类型约束;已有大量 SharedPreferences 的迁移项目先用 Preferences DataStore 快速替换,后续再升级为 Proto。
| 依赖 | Artifact | 用途 |
|---|---|---|
| Preferences DataStore | androidx.datastore:datastore-preferences:1.1.1 | 键值对存储,替代 SharedPreferences |
| Proto DataStore | androidx.datastore:datastore:1.1.1 | 基于 Protocol Buffers 的类型安全存储 |
| Protobuf 编译器 | com.google.protobuf:protobuf-javalite:3.25.3 | 仅 Proto DataStore 需要,用于生成 Java 代码 |
在模块级 build.gradle(kts 或 groovy)中添加依赖:
// build.gradle.kts (模块级)
dependencies {
// Preferences DataStore
implementation("androidx.datastore:datastore-preferences:1.1.1")
// Proto DataStore + Protobuf
implementation("androidx.datastore:datastore:1.1.1")
implementation("com.google.protobuf:protobuf-javalite:3.25.3")
}
3.2 配置 Gradle 版本与插件
DataStore 1.1.x 系列需要满足以下最低版本要求,否则可能出现无法解析或运行时异常。
| 组件 | 最低版本 | 建议版本 |
|---|---|---|
| Android Gradle Plugin (AGP) | 7.0 | 8.2+ |
| Kotlin | 1.6.0 | 1.9.22 |
| Gradle | 7.0 | 8.5+ |
| compileSdk / targetSdk | 31 | 34 |
在项目级 build.gradle.kts 声明正确的 Gradle 版本:
// build.gradle.kts (项目级)
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.2.2")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22")
}
}
// gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
常见错误: 如果 Kotlin 版本低于 1.6.0,DataStore Flow 的
collect 在协程中会报 NoSuchMethodError。务必先升级 Kotlin 插件再添加 DataStore 依赖。
3.3 迁移前备份策略
替换 SharedPreferences 时,必须确保旧数据在新存储初始化完成前被完整保留。推荐采用 “复制并标记” 策略:
- 在首次启动迁移时,将 SharedPreferences 中的全部键值对复制到 DataStore。
- 复制完成后,在 DataStore 中写入一个标记键(如
migrated_to_datastore)。 - 此后每次启动检查该标记:若存在则跳过迁移;若不存在则再次执行备份复制。
- 旧 SharedPreferences 文件保留至少两个版本周期,确认无回滚后再删除。
备份实现核心代码片段:
// BackupManager.kt
suspend fun backupSharedPrefs(
context: Context,
dataStore: DataStore<Preferences>
) {
val prefs = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
val migratedKey = booleanPreferencesKey("migrated_to_datastore")
val alreadyMigrated = dataStore.data.first()[migratedKey] ?: false
if (alreadyMigrated) return
// 复制所有键值对
prefs.all.forEach { (key, value) ->
when (value) {
is String -> dataStore.edit { it[stringPreferencesKey(key)] = value }
is Int -> dataStore.edit { it[intPreferencesKey(key)] = value }
is Boolean -> dataStore.edit { it[booleanPreferencesKey(key)] = value }
is Float -> dataStore.edit { it[floatPreferencesKey(key)] = value }
is Long -> dataStore.edit { it[longPreferencesKey(key)] = value }
is Set<*> -> dataStore.edit {
it[stringSetPreferencesKey(key)] = value as Set<String>
}
}
}
// 写入迁移标记
dataStore.edit { it[migratedKey] = true }
}
性能提示: 不要在 UI 线程执行备份,使用
scope.launch(Dispatchers.IO)。如果 SharedPreferences 数据量超过 200 个键,建议将复制分批执行,避免 DataStore 单次事务过大。
3.4 环境搭建流程总览
3.5 常见错误与解决
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
| Cannot inline bytecode built with JVM target 1.8 into bytecode built with JVM target 11 | Kotlin JVM target 不一致 | 在 build.gradle.kts 中设置 kotlin.jvmOptions.jvmTarget = "11" |
| Failed to resolve: datastore-preferences | 缺少 google() 仓库 | 确保 repositories { google() } 在项目级和模块级都存在 |
| Proto DataStore 生成代码时找不到 proto 文件 | protobuf 插件未正确配置 | 在模块级 build.gradle.kts 中添加 protobuf { ... } 块并指定 src/main/proto 目录 |
3.6 部署前检查清单
- Gradle 同步成功:无红色波浪线,依赖解析正确。
- 备分代码已注入 Application 或 LauncherActivity:确保在首次访问 DataStore 前执行。
- 迁移标记持久化验证:手动卸载 App 重装后迁移不会重复执行(需配合
encryptedSharedPreferences或云端备份策略)。 - 回滚预案:在旧 SharedPreferences 文件未被删除前,一旦 DataStore 出现崩溃可快速切回旧方案。
最佳实践: 将备份逻辑放在
Application.onCreate() 中,使用 lifecycleScope.launch(Dispatchers.IO) 异步执行,不影响冷启动时间。