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 库,引入SQLiteDriver、setDriver()、useReaderConnection()、useWriterConnection(),并把room-ktx合并进room-runtime。2.8开始,官方补上了room-sqlite-wrapper,让大项目可以渐进式从SupportSQLite迁到SQLiteDriver,同时 AndroidminSdk从21提升到23。- 到了
3.0.0-alpha01,官方直接启用新包名androidx.room3,把 Kotlin、KSP、协程优先、Driver 化这些方向彻底做实。
这篇文章就按这个脉络,讲清楚 5 件事:
- Room 3.0 到底更新了什么。
- 它和旧版 Room 最大的不同是什么。
- 哪些项目适合现在升级,哪些项目不适合。
- Room 3.0 现在应该怎么用。
- 从 Room 2.x 升到 3.0,推荐怎么迁。
一、先看版本时间线:为什么 Room 3.0 会“看起来像重写了一遍”
| 版本 | 官方时间 | 关键变化 |
|---|---|---|
2.6.0-alpha02 | 2023-06-21 | 引入 Room Gradle Plugin,插件 id 为 androidx.room,用于稳定导出 schema。 |
2.6.0 | 2023-10-18 | Kotlin CodeGen 逐步走向主流,KSP 支持继续增强。 |
2.7.0 | 2025-04-09 | Room 正式支持 KMP;引入 SQLiteDriver、setDriver()、useReaderConnection()、useWriterConnection();支持 SQLiteConnection 回调;room-ktx 合并进 room-runtime;要求 Kotlin 2.0,推荐 KSP2。 |
2.8.0 | 2025-09-10 | 新增 room-sqlite-wrapper 用于渐进迁移;新增 Watch OS / Tv OS 支持;Android minSdk 从 21 提升到 23。 |
2.8.4 | 2025-11-19 | 当前稳定版,主要是性能和 schema 校验修复。 |
3.0.0-alpha01 | 2026-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 时代,很多项目会直接或间接依赖这些能力:
SupportSQLiteDatabaseSupportSQLiteOpenHelperCursorroomDatabase.openHelper.writableDatabaseroomDatabase.query(...)runInTransaction { ... }
到了 Room 3.0,官方明确说明:
- Room 3.0 完全建立在
SQLiteDriverAPI 之上。 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.ObserveraddObserver()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 继续往前走,新增:
JSWasmJS
同时配合 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-pagingRxJava3对应room3-rxjava3Guava对应room3-guavaLiveData对应room3-livedata
但和旧版不同的是,这些类型现在需要通过 @DaoReturnTypeConverters 显式注册。
这件事的本质是:Room 3.0 不再只是“内置支持几个常见框架”,而是把 DAO 返回类型扩展能力正式抽象成了一个平台级机制。
三、Room 3.0 和旧版 Room,到底有哪些一眼能看懂的差别
| 维度 | Room 2.x | Room 3.0 |
|---|---|---|
| Maven 坐标 | androidx.room:* | androidx.room3:room3-* |
| 包名 | androidx.room | androidx.room3 |
| 注解处理 | KAPT / KSP / JavaAP 都能覆盖一部分场景 | KSP 必须 |
| 代码生成 | Java / Kotlin 混合过渡期 | 只生成 Kotlin |
| 底层数据库 API | SupportSQLite 为主,可逐步接入 SQLiteDriver | SQLiteDriver 为主 |
| 事务与查询 | runInTransaction()、query() 等旧式 API 常见 | withWriteTransaction()、useReaderConnection()、useWriterConnection() |
| 失效监听 | InvalidationTracker.Observer | InvalidationTracker.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.x或2.8.x。 - 已经迁到 KSP。
- DAO 已经大量使用
suspend/Flow。 - 项目本来就准备上 KMP,或者已经在 Android / iOS / Desktop 共享数据层。
- 你能接受 alpha 版本带来的不稳定性,并且升级是在独立分支或 PoC 中进行。
暂时不要直接上 Room 3.0 的项目
- 生产环境 Android-only 业务项目,当前首要目标是稳定交付。
- 仍然重度依赖 Java、KAPT、
annotationProcessor。 - 底层大量使用
SupportSQLiteDatabase、Cursor、OpenHelper。 - 仍然在用
InvalidationTracker.Observer这类老监听方案。 - 你的版本兼容还卡在 Android
API 21/22。
最后这一条要特别注意。
官方已经在 Room 2.8.0 中把 Android minSdk 从 21 提升到了 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-ktx在2.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.4、2.5、2.6,直接跳到 3.0 往往不是技术上不可能,而是成本不可控。
第 2 步:把 schema 和 migration 测试先补齐
官方的自动迁移和 MigrationTestHelper 都依赖导出的 schema。
建议至少做到:
exportSchema = true- 配置
room或room3的schemaDirectory - 为关键版本升级链补一套 migration tests
如果连 schema 都没导出来,你的升级过程基本只能靠运气。
第 3 步:先把底层 SupportSQLite 用法收口
先在项目里全局搜这些关键词:
SupportSQLiteDatabaseSupportSQLiteQueryopenHelper.writableDatabaseCursorquery(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 值得你尽早开一个分支认真验证。