Android Room 3.0 已经来了,但你现在真的该升级吗?官方更新解读与迁移指南

0 阅读9分钟

Android Room 3.0 已经来了,但你现在真的该升级吗?官方更新解读与迁移指南

基于 Android Developers 官方文档整理,时间点为 2026-03-17
先说结论:Room 的最新版本线已经来到 3.0.0-alpha01,发布时间是 2026-03-11;但最新稳定版仍然是 2.8.4,发布时间是 2025-11-19
所以如果你最近看到“Room 已经 3.x 了”,这句话只对了一半:是的,版本线到了 3.0;但生产环境默认选择仍然应该优先看 2.8.4,而不是直接上 3.0 alpha。

很多同学会觉得 Room 3.0 只是一次大版本号升级,但我翻完官方 release notes 之后的判断是:这其实是从 Room 2.6、2.7、2.8 一路演进之后的一次架构收口。

如果只看 3.0,你会觉得变化很大;如果把 2.7 和 2.8 一起看,脉络就很清楚了:

  • 2.6 开始,Room 正式把 Gradle Plugin、Kotlin CodeGen 这些能力推上台面。
  • 2.7 开始,Room 被重构为 Kotlin Multiplatform 库,引入 SQLiteDriversetDriver()useReaderConnection()useWriterConnection(),并把 room-ktx 合并进 room-runtime
  • 2.8 开始,官方补上了 room-sqlite-wrapper,让大项目可以渐进式从 SupportSQLite 迁到 SQLiteDriver,同时 Android minSdk21 提升到 23
  • 到了 3.0.0-alpha01,官方直接启用新包名 androidx.room3,把 Kotlin、KSP、协程优先、Driver 化这些方向彻底做实。

这篇文章就按这个脉络,讲清楚 5 件事:

  1. Room 3.0 到底更新了什么。
  2. 它和旧版 Room 最大的不同是什么。
  3. 哪些项目适合现在升级,哪些项目不适合。
  4. Room 3.0 现在应该怎么用。
  5. 从 Room 2.x 升到 3.0,推荐怎么迁。

一、先看版本时间线:为什么 Room 3.0 会“看起来像重写了一遍”

版本官方时间关键变化
2.6.0-alpha022023-06-21引入 Room Gradle Plugin,插件 id 为 androidx.room,用于稳定导出 schema。
2.6.02023-10-18Kotlin CodeGen 逐步走向主流,KSP 支持继续增强。
2.7.02025-04-09Room 正式支持 KMP;引入 SQLiteDriversetDriver()useReaderConnection()useWriterConnection();支持 SQLiteConnection 回调;room-ktx 合并进 room-runtime;要求 Kotlin 2.0,推荐 KSP2。
2.8.02025-09-10新增 room-sqlite-wrapper 用于渐进迁移;新增 Watch OS / Tv OS 支持;Android minSdk21 提升到 23
2.8.42025-11-19当前稳定版,主要是性能和 schema 校验修复。
3.0.0-alpha012026-03-11新包名 androidx.room3;不再支持 SupportSQLite 主路径;所有数据库操作转向协程 API;只支持 Kotlin codegen;必须使用 KSP;新增 JS / WasmJS 支持和自定义 DAO 返回类型转换器。

从这个时间线你就能看出来,Room 3.0 不是“突然改了很多”,而是把 2.7 和 2.8 里已经铺好的路线彻底落实了。

二、Room 3.0 的核心变化,到底大在哪

1. 包名和坐标全部换了

这是 Room 3.0 最表面的变化,但它其实非常关键。

Room 2.x:

implementation("androidx.room:room-runtime:2.8.4")
ksp("androidx.room:room-compiler:2.8.4")

Room 3.0:

implementation("androidx.room3:room3-runtime:3.0.0-alpha01")
ksp("androidx.room3:room3-compiler:3.0.0-alpha01")

代码里的包名也会从:

import androidx.room.*

变成:

import androidx.room3.*

官方之所以这么做,是为了避免和 Room 2.x 以及带有 Room 传递依赖的库发生兼容性问题,比如 WorkManager 这类 Jetpack 组件。

这意味着 Room 3.0 不是一次“无感升级”,而是明确的迁移。

2. SupportSQLite 不再是主路径,SQLiteDriver 成为核心

这是 Room 3.0 真正最重的变化。

在 Room 2.x 时代,很多项目会直接或间接依赖这些能力:

  • SupportSQLiteDatabase
  • SupportSQLiteOpenHelper
  • Cursor
  • roomDatabase.openHelper.writableDatabase
  • roomDatabase.query(...)
  • runInTransaction { ... }

到了 Room 3.0,官方明确说明:

  • Room 3.0 完全建立在 SQLiteDriver API 之上。
  • SupportSQLite 不再被主路径支持。
  • 构建 RoomDatabase 时,SQLiteDriver 成为必需项。

官方给出的典型对比很直观:

// Room 2.x
roomDatabase.runInTransaction { ... }

// Room 3.x
roomDatabase.withWriteTransaction { ... }
// Room 2.x
roomDatabase.query("SELECT * FROM Song").use { cursor -> ... }

// Room 3.x
roomDatabase.useReaderConnection { connection ->
    connection.usePrepared("SELECT * FROM Song") { stmt ->
        // ...
    }
}

如果你的项目里有很多底层 SQL、Cursor、OpenHelper 代码,这一条就是升级成本的主要来源。

3. Room 3.0 是真正的 Kotlin + Coroutines First

Room 2.x 虽然早就支持协程,但它本质上还兼容很多旧路径。

Room 3.0 则是直接把方向定死了:

  • 只生成 Kotlin 代码
  • 只能走 KSP
  • 数据库操作统一以协程 API 为中心

这会带来几个非常实际的影响:

  • Java + annotationProcessor / KAPT 的旧配置,到了 3.0 不能继续原样使用。
  • DAO 函数如果不是响应式返回类型,就应该改为 suspend
  • Executor 配置思路退场,官方强调用 CoroutineContext 来配置。

需要注意的是,官方同时说明:KSP 仍然可以处理 Java 源码
也就是说,你不是必须把整个项目一次性改成纯 Kotlin,但至少要把 Room 所在模块切换到 KSP 这条链路。

4. InvalidationTracker.Observer 被移除了,改成 Flow

如果你以前做过复杂缓存刷新、跨表监听、Repository 级联更新,可能写过这套老 API:

  • InvalidationTracker.Observer
  • addObserver()
  • removeObserver()

Room 3.0 里这套 API 被拿掉了,官方要求改成 Flow 方案,通过 InvalidationTracker.createFlow() 响应表变更。

这说明 Room 团队已经不再把“面向回调的失效监听”当作长期演进方向,而是把 Flow 作为标准方案。

5. 3.0 不只是 KMP,它还把 Web 也带进来了

Room 2.7 把 Room 推进到了 Android、iOS、JVM、macOS、Linux。

Room 3.0 继续往前走,新增:

  • JS
  • WasmJS

同时配合 androidx.sqlite:sqlite-web 中的 WebWorkerSQLiteDriver,Room 已经具备跨 Web 运行的基础能力。

这件事的意义不是“你明天就拿 Room 写浏览器应用”,而是说明 Room 的设计目标已经不是 Android-only ORM 了,而是真正的跨平台本地数据层

6. DAO 返回类型的扩展方式彻底升级

在 Room 2.x 里,Paging、RxJava、Guava、LiveData 这些集成更多是“官方直接给你一个 artifact,然后自动接起来”。

在 Room 3.0 里,官方把这件事升级成了 DAO return type converters

  • PagingSource 对应 room3-paging
  • RxJava3 对应 room3-rxjava3
  • Guava 对应 room3-guava
  • LiveData 对应 room3-livedata

但和旧版不同的是,这些类型现在需要通过 @DaoReturnTypeConverters 显式注册。

这件事的本质是:Room 3.0 不再只是“内置支持几个常见框架”,而是把 DAO 返回类型扩展能力正式抽象成了一个平台级机制。

三、Room 3.0 和旧版 Room,到底有哪些一眼能看懂的差别

维度Room 2.xRoom 3.0
Maven 坐标androidx.room:*androidx.room3:room3-*
包名androidx.roomandroidx.room3
注解处理KAPT / KSP / JavaAP 都能覆盖一部分场景KSP 必须
代码生成Java / Kotlin 混合过渡期只生成 Kotlin
底层数据库 APISupportSQLite 为主,可逐步接入 SQLiteDriverSQLiteDriver 为主
事务与查询runInTransaction()query() 等旧式 API 常见withWriteTransaction()useReaderConnection()useWriterConnection()
失效监听InvalidationTracker.ObserverInvalidationTracker.createFlow()
响应式集成直接依赖对应 artifact 即可通过 @DaoReturnTypeConverters 显式注册
平台范围Android 为主,2.7 起支持 KMP在 KMP 基础上继续扩展到 JS/WasmJS

一句话总结:

Room 2.x 是“从 Android Room 逐步长成 multiplatform Room”;Room 3.0 则是“按 multiplatform-first 的思路重新划定边界”。

四、兼容性怎么判断:哪些项目适合现在升,哪些项目不适合

适合现在开始评估 Room 3.0 的项目

  • 已经在使用 2.7.x2.8.x
  • 已经迁到 KSP。
  • DAO 已经大量使用 suspend / Flow
  • 项目本来就准备上 KMP,或者已经在 Android / iOS / Desktop 共享数据层。
  • 你能接受 alpha 版本带来的不稳定性,并且升级是在独立分支或 PoC 中进行。

暂时不要直接上 Room 3.0 的项目

  • 生产环境 Android-only 业务项目,当前首要目标是稳定交付。
  • 仍然重度依赖 Java、KAPT、annotationProcessor
  • 底层大量使用 SupportSQLiteDatabaseCursorOpenHelper
  • 仍然在用 InvalidationTracker.Observer 这类老监听方案。
  • 你的版本兼容还卡在 Android API 21/22

最后这一条要特别注意。

官方已经在 Room 2.8.0 中把 Android minSdk21 提升到了 23
所以如果你的项目还要继续覆盖 21/22,那么你连 2.8 这一步都不能无脑上,更不用说直接追到 3.0。

另外,如果你正在使用 Room Gradle Plugin,那么官方在 2.8.0-rc02 还把与 Room 插件兼容的最低 AGP 版本从 8.1 提升到了 8.4。这也是升级前必须确认的构建条件。

五、Room 3.0 现在应该怎么用

先说一个实际建议:如果你只是 Android 单平台项目,且没有明确的 KMP 或 Driver 迁移计划,那么现在学习 3.0 时,不要把重点放在“语法变了多少”,而要放在“架构边界变了什么”。

下面给一套更接近官方新思路的写法。

1. Gradle 依赖

plugins {
    id("com.google.devtools.ksp") version "<ksp_version>"
    id("androidx.room3") version "3.0.0-alpha01"
}

dependencies {
    implementation("androidx.room3:room3-runtime:3.0.0-alpha01")
    ksp("androidx.room3:room3-compiler:3.0.0-alpha01")

    // 推荐的 SQLite Driver
    implementation("androidx.sqlite:sqlite-bundled:2.6.2")

    // 如果迁移期还需要兼容旧的 SupportSQLite 代码,可临时引入
    implementation("androidx.room3:room3-sqlite-wrapper:3.0.0-alpha01")
}

room3 {
    schemaDirectory("$projectDir/schemas")
}

这里有几个点要一起记住:

  • Room 3.0 插件 id 是 androidx.room3
  • schemaDirectory 仍然很重要,因为 auto migration 和 migration test 都依赖 schema 导出。
  • room-ktx2.7 就已经合并进 room-runtime 了,不要再沿用旧依赖习惯。

2. 实体、DAO、Database 写法

注解模型本身没有被推翻,@Entity@Dao@Database 这些核心概念还在。

import androidx.room3.Database
import androidx.room3.Entity
import androidx.room3.Insert
import androidx.room3.PrimaryKey
import androidx.room3.Query
import androidx.room3.RoomDatabase
import kotlinx.coroutines.flow.Flow

@Entity(tableName = "user")
data class UserEntity(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val name: String,
    val age: Int,
)

@androidx.room3.Dao
interface UserDao {
    @Query("SELECT * FROM user ORDER BY id DESC")
    fun observeUsers(): Flow<List<UserEntity>>

    @Insert
    suspend fun insert(user: UserEntity)
}

@Database(
    entities = [UserEntity::class],
    version = 1,
    exportSchema = true,
)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

这里最关键的不是注解,而是两个迁移方向:

  • 写操作、单次读操作尽量 suspend
  • 可观察查询尽量统一到 Flow

3. 数据库实例化

import androidx.room3.Room
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import kotlinx.coroutines.Dispatchers

fun createDatabase(path: String): AppDatabase {
    return Room.databaseBuilder<AppDatabase>(name = path)
        .setDriver(BundledSQLiteDriver())
        .setQueryCoroutineContext(Dispatchers.IO)
        .build()
}

如果你是 Android-only 项目,path 一般可以来自:

val dbPath = context.getDatabasePath("app.db").absolutePath

这段代码表面上只是换了个 builder,但背后的设计变化很大:

  • 你不再通过 SupportSQLiteOpenHelper 间接控制底层实现。
  • 你要明确选择 SQLiteDriver
  • 你要用协程上下文而不是老式 Executor 思路来配置执行环境。

六、从 Room 2.x 升到 3.0,推荐按这 6 步走

我不建议直接在主干分支里“一把梭”升 Room 3.0。
官方资料看完之后,我更推荐下面这条渐进路径。

第 1 步:先把项目升级到 Room 2.7 / 2.8 的现代基线

这一步的目标不是马上上 3.0,而是先把历史包袱卸掉。

优先做这些事:

  • 从 KAPT / annotationProcessor 迁到 KSP。
  • 删除 room-ktx 依赖。
  • 引入 Room Gradle Plugin。
  • 打开 schema 导出并提交到仓库。
  • 确认 Kotlin 版本至少满足 2.7 之后的要求。

如果你现在还停在 2.42.52.6,直接跳到 3.0 往往不是技术上不可能,而是成本不可控。

第 2 步:把 schema 和 migration 测试先补齐

官方的自动迁移和 MigrationTestHelper 都依赖导出的 schema。

建议至少做到:

  • exportSchema = true
  • 配置 roomroom3schemaDirectory
  • 为关键版本升级链补一套 migration tests

如果连 schema 都没导出来,你的升级过程基本只能靠运气。

第 3 步:先把底层 SupportSQLite 用法收口

先在项目里全局搜这些关键词:

  • SupportSQLiteDatabase
  • SupportSQLiteQuery
  • openHelper.writableDatabase
  • Cursor
  • query(
  • InvalidationTracker.Observer

如果命中很多,不要直接切到 Room 3.0。
更稳妥的方式是先在 Room 2.8.x 上使用 room-sqlite-wrapper 做过渡,把旧代码一层层收口。

迁移期可以这么理解:

  • 新路径优先用 SQLiteDriver
  • 旧路径临时通过 getSupportWrapper() 桥接
  • 等桥接点逐步减少,再切到 room3-sqlite-wrapper 或完全去掉 wrapper

第 4 步:把 DAO 统一到 suspend / Flow

Room 3.0 的世界里,阻塞式 DAO 已经不是主流路径。

推荐改法:

  • fun getAll(): List<User> -> suspend fun getAll(): List<User>
  • LiveData<List<User>> 这类 Android-only 响应式返回,优先评估是否改为 Flow<List<User>>
  • 对于 Paging / RxJava / Guava / LiveData 这类特殊返回类型,升级到 3.0 后通过 @DaoReturnTypeConverters 显式注册

如果你的 Repository、UseCase、ViewModel 还没有协程化,这一步往往比改依赖更费时间。

第 5 步:再切换到 Room 3.0 的依赖、插件和包名

这一层改动会比较机械,但也最容易漏。

典型替换如下:

- implementation("androidx.room:room-runtime:2.8.4")
- implementation("androidx.room:room-ktx:2.8.4")
- ksp("androidx.room:room-compiler:2.8.4")
+ implementation("androidx.room3:room3-runtime:3.0.0-alpha01")
+ ksp("androidx.room3:room3-compiler:3.0.0-alpha01")
+ implementation("androidx.sqlite:sqlite-bundled:2.6.2")
- id("androidx.room")
+ id("androidx.room3")
- room {
+ room3 {
    schemaDirectory("$projectDir/schemas")
}

同时别忘了:

  • androidx.room.* -> androidx.room3.*
  • androidx.room:room-sqlite-wrapper -> androidx.room3:room3-sqlite-wrapper

第 6 步:最后处理监听器、回调和低层 SQL 代码

这一步才是真正把“2.x 思维”切换成“3.0 思维”。

重点看这些点:

  • InvalidationTracker.Observer 改成 createFlow()
  • 迁移回调、自动迁移回调、数据库回调,逐步切到 SQLiteConnection 新路径
  • 底层 SQL 从 query + Cursor 迁到 useReaderConnection / usePrepared
  • 如果目标包含 Web,相关回调和 Driver API 还要考虑异步 / suspend 语义

七、一个更现实的升级建议:大多数团队现在不该“直接升 3.0”,而该“先完成 2.8 现代化”

如果你问我一句最务实的话,我的答案会是:

现在大多数 Android 团队最正确的动作,不是立刻把 Room 升到 3.0,而是先把项目整理到“随时可升 3.0”的状态。

具体来说:

  • 生产项目默认目标版本:2.8.4
  • 架构升级目标:KSP、schema 导出、DAO 协程化、SQLiteDriver
  • 技术预研目标:单开分支验证 3.0.0-alpha01

这样做的好处是:

  • 线上风险最低
  • 团队改造成本可控
  • 等 3.0 进入 beta / rc 时,你几乎不需要再做第二轮大手术

八、结论

Room 3.0 真正重要的不是“大版本号”,而是它把 Room 的边界重画了一次。

它告诉我们几件非常明确的事:

  • Room 的未来不是 Android-only,而是 multiplatform-first。
  • Room 的底层不再以 SupportSQLite 为中心,而是以 SQLiteDriver 为中心。
  • Room 的默认编程模型不再是“兼容 Java 老链路”,而是 Kotlin + KSP + Coroutines。

所以,面对 Room 3.0,正确的问题不是“我能不能今天就升”,而是:

我的项目,是否已经准备好进入这条新主线。

如果答案是否定的,那就先把 2.8 这一步走扎实。
如果答案是肯定的,尤其你已经在做 KMP 或共享数据层,那么 Room 3.0 值得你尽早开一个分支认真验证。

官方参考链接