3. 在 Android 项目中添加 Room 依赖:build.gradle 配置与版本选择

这一章我们聊聊怎么把 Room 请进项目里。说白了就是两件事:选对版本和配对依赖。很多新手在这一步踩坑,我当年也被版本兼容问题折磨过好几个晚上。嗯,咱们直接动手。

3.1 项目级 build.gradle — 加个插件

Room 需要注解处理器来生成代码。如果你用的是 Kotlin,你需要在项目级的 build.gradle.kts 里声明 KSP 或者 KAPT 插件。我个人习惯用 KSP,因为编译速度更快,尤其在大型项目里优势明显。

提示:KSP 从 Room 2.6.0 开始成为官方首选。如果你还在用 2.5.x 及以下,只能选 KAPT。建议新项目直接上 Room 2.6+ 配合 KSP。
// 项目级 build.gradle.kts
plugins {
    id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false
    // 如果要用 KAPT,则换成:
    // id("org.jetbrains.kotlin.kapt") version "1.9.0"
}

注意版本号要跟你的 Kotlin 版本匹配。KSP 的版本号格式是 Kotlin版本-处理器版本。比如 Kotlin 1.9.0 对应 KSP 1.9.0-1.0.13。每次更新 Kotlin 都得同步更新 KSP,否则编译直接报错。

3.2 模块级 build.gradle — 依赖列表

打开你的 app 模块(或 data 模块)的 build.gradle.kts,在 plugins 块里启用刚刚声明的插件:

// 模块级 build.gradle.kts
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.devtools.ksp")    // 如果用 KAPT,则改为 id("org.jetbrains.kotlin.kapt")
}

android {
    // ... 你的 android 配置
}

dependencies {
    val roomVersion = "2.6.1"
    implementation("androidx.room:room-runtime:$roomVersion")
    implementation("androidx.room:room-ktx:$roomVersion")        // Kotlin 扩展,强烈建议加上
    implementation("androidx.room:room-rxjava2:$roomVersion")    // 如果你用 RxJava,否则跳
    ksp("androidx.room:room-compiler:$roomVersion")             // 处理器,KSP 版
    // 如果用了 KAPT,则改为:
    // kapt("androidx.room:room-compiler:$roomVersion")
}

这里有三个必配项:room-runtime(核心库)、room-ktx(支持协程和 Flow,我项目里每次都加)、room-compiler(代码生成器)。room-rxjava2 是可选的,看你项目是否需要。

重点:处理器(编译期依赖)一定要用 ksp() 或 kapt(),不要写成 implementation,否则运行时不会报错,但 DAO 方法调用时闪退,排查起来非常头疼。我曾经就在这个低级错误上浪费了两小时。

3.3 版本选择与兼容性

Room 版本不是想升就升的,它跟 Kotlin、AGP(Android Gradle Plugin)、甚至 JDK 都有关系。我给你整理了一张表,是我自己项目里验证过的:

Room 版本最低 Kotlin 版本最低 AGP 版本推荐 Java 编译级别处理器选项
2.4.0 – 2.4.31.6.04.2.01.8kapt
2.5.0 – 2.5.21.7.07.2.01.8 或 11kapt(KSP 实验性)
2.6.0 – 2.6.11.8.07.4.011 或 17ksp(推荐)/ kapt

为什么会这样?因为 Room 的注解处理器使用了 Kotlin 的内部 API,Kotlin 大版本升级时,Room 需要适配才能正常工作。同样,AGP 升级也可能影响 Gradle 的编译流程。我建议你统一使用 Room 2.6.1 + Kotlin 1.9.x + AGP 8.x,这是目前最稳的组合。

避坑指南:我曾经把一个老项目的 Room 从 2.4.3 直接跳到 2.6.1,而 Kotlin 还卡在 1.6.0,结果编译通过了,但运行时报 NoSuchMethodError。查了半天发现是 Room 的 coroutine 扩展依赖于 Kotlin 1.8 才有的新函数。所以版本对齐一定要看官方文档的兼容性说明。

3.4 选择 KSP 还是 KAPT?

这其实是 Room 依赖配置里绕不开的话题。我给个结论:新项目一律用 KSP。理由有三:

  • 编译快:KSP 直接操作符号树,不需要生成 Java 存根文件。我在一个中型项目(50+ DAO)里对比过,KSP 比 KAPT 快 40% 左右。
  • 增量编译:KSP 原生支持增量,而 KAPT 在多模块下经常回退到全量编译。
  • 维护性:Google 已将 Room 的 KSP 支持列为稳定功能,未来甚至会逐步淘汰 KAPT 方案。

如果你因为某些原因必须用 KAPT(比如还在用 Room 2.5.x 且不想动 Kotlin 版本),那就继续用。不过要注意,KAPT 在 Gradle 8.0+ 上可能需要额外配置:

// 如果使用 KAPT + AGP 8.x,可能需要添加:
kapt {
    correctErrorTypes = true
}

否则可能报错 Type arguments are not fully inferred。

3.5 整体配置流程

下面这张图总结了 Room 依赖配置的完整路径,你照着来就行:

Room 依赖配置流程 项目级 build.gradle KSP 插件(推荐) com.google.devtools.ksp KAPT 插件(备用) org.jetbrains.kotlin.kapt 模块级 build.gradle room-runtime 核心库(必须) room-ktx 协程扩展(推荐) room-compiler 处理器(ksp/kapt) 提示:处理器依赖必须使用 ksp() / kapt() 而非 implementation(),否则运行时报错

3.6 常见错误与修复

我在回答别人问题时常遇到这几个坑,列出来你直接对号入座:

  1. 依赖写好了但编译报错:kapt 未定义。 → 模块级 build.gradle 忘记在 plugins 块里启用 kapt 或 ksp 插件。
  2. 房间编译通过但 DAO 方法返回空。 → 检查 room-compiler 是否误写成 implementation。必须用 kapt 或 ksp。
  3. 升级 Room 后出现 MissingMethod。 → 大多是因为 Kotlin 版本太低。对照上面的兼容性表升级 Kotlin。
  4. 多模块项目报错:Duplicate class。 → 不同模块重复引入了 Room 依赖。建议只在 data 模块添加,其他模块通过 implementation project() 引用。
小技巧:配置完后先跑一遍 ./gradlew app:dependencies --configuration ksp(或 kapt)查看依赖树。如果 room-compiler 没有出现在结果里,说明它被忽略了。

最后补充一句:Room 的版本和处理器选择不是一劳永逸的。每次 Android Studio 升级或者 Kotlin 新版本发布,都建议回来看一眼官方 Release Notes。我每次升级前都会先在一个分支里试跑,确保 build.gradle 配置没问题再合并。这样虽然慢一点,但省去了半夜改 bug 的麻烦。