agp 9.0+ 的内置 kotlin 由插件自身绑定(如 kotlin 1.9.20),不可单独升降级,仅负责编译 .kt 文件;项目 kotlin 版本则决定语言特性、ide 检查及 kotlin-stdlib 依赖,二者不一致会导致构建成功但 ide 报错、noclassdeffounderror 或 jvmtarget 失效等问题。

内置Kotlin版本由AGP控制,不等于你项目里写的Kotlin代码版本
AGP 9.0+ 的「内置 Kotlin」指的是一套由 Android Gradle 插件自身打包、预配置的 Kotlin 编译器和 DSL 支持逻辑——它负责把 .kt 源文件编译成字节码,并处理 kotlinOptions、sourceSets 等基础构建行为。这个内置版本是 AGP 内部绑定的(比如 AGP 9.0 对应 Kotlin 1.9.20),你无法单独升级或降级它,也不需要在 build.gradle 里声明 org.jetbrains.kotlin.android 插件。
而「项目 Kotlin 版本」指的是你在 build.gradle 或 gradle.properties 中显式设置的 kotlinVersion,或者通过 libs.versions.toml 声明的 Kotlin 编译器版本,它影响的是:你在 .kt 文件中能用哪些语言特性(如 val x: Int? = null 是基础语法,但 sealed interface 就需要 Kotlin 1.7+)、IDE 的语法检查、以及 Kotlin 标准库(kotlin-stdlib)的依赖版本。
二者不一致时,最常见现象是:
- IDE 显示「Unresolved reference」但构建成功(IDE 用的是项目 Kotlin 版本做语义分析,而 AGP 用内置版本编译)
- 构建报错
Kotlin version mismatch: API version is 1.9, but classpath contains 1.8(kotlin-stdlib依赖版本与内置编译器不兼容) -
kotlinOptions.jvmTarget不生效(AGP 9.0+ 要求 jvmTarget 必须 ≤ 内置 Kotlin 支持的最高目标版本)
为什么移除 kotlin-android 后,kotlinVersion 还要手动对齐
移除插件只是去掉重复注册的编译逻辑,不是去掉 Kotlin 语言本身。项目仍需明确指定 kotlin-stdlib 的版本,否则 Gradle 可能拉取一个与内置编译器不匹配的旧版 stdlib(比如内置用 Kotlin 1.9.20 编译,却引入了 1.8.0 的 stdlib,运行时会抛 NoClassDefFoundError)。
正确做法是统一通过以下任一方式声明 Kotlin 版本:
- 在
gradle/libs.versions.toml中定义:kotlin = "1.9.20",然后所有模块用implementation libs.kotlin.stdlib - 在
build.gradle.kts的dependencies块中写死:implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.20") - 避免在
gradle.properties中设kotlin.version=1.8.0—— 这种全局变量容易被旧脚本残留引用,且 AGP 9.0+ 已不读取它
kotlinOptions 和 sourceSets 迁移时最容易忽略的兼容性断点
AGP 9.0 内置 Kotlin 并非简单“复制粘贴”旧插件逻辑,而是重构了 DSL 解析路径。这意味着部分旧写法会静默失效或触发构建错误:
-
kotlinOptions.freeCompilerArgs += "-Xjvm-default=all":必须改用kotlinOptions.freeCompilerArgs.add("-Xjvm-default=all"),否则参数不生效 -
sourceSets.getByName("main").kotlin.srcDirs("src/main/kotlin"):AGP 9.0+ 默认已包含该路径,显式添加会导致重复扫描,引发Duplicate source root警告 -
kotlinOptions.apiVersion = "1.8":已被废弃,改用kotlinOptions.languageVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_8,否则构建失败 - 如果用了
kotlin-kapt,必须保留插件声明(id("org.jetbrains.kotlin.kapt")),但要确保其版本与内置 Kotlin 兼容(如 AGP 9.0 → kapt 1.9.20)
多模块项目里,Kotlin 版本不一致的坑比想象中深
一个常见误操作是:只升级了 :app 模块的 kotlin-stdlib,但 :core、:data 等库模块仍用旧版。这会导致运行时类加载冲突——比如 :app 用 1.9.20 编译调用了 StandardKt.requireNotNull,而 :core 的 1.8.0 stdlib 里根本没有这个符号。
更隐蔽的问题是 KAPT 注解处理器:若 :data 模块用 kapt 生成代码,而 :app 模块没声明 kotlin-kapt 插件,AGP 会跳过注解处理,导致编译期找不到生成的 DAO 类。
所以迁移时必须:
- 全模块统一
kotlin-stdlib版本(建议用 Version Catalog 管理) - 每个含 Kotlin 源码的模块都检查是否遗漏
kotlin-kapt(仅当用到注解处理器时) - 禁用
android.builtInKotlin=false后,立刻运行./gradlew :app:assembleDebug --scan查看实际参与编译的 Kotlin 版本来源











