Gradle 7.0+ 应在 settings.gradle.kts 顶部用 pluginManagement 块统一声明插件版本,禁止使用 buildSrc/ext/gradle.properties;需配合 resolutionStrategy 强制约束未声明版本的插件,并注意 AGP 与 Kotlin 版本强耦合。

用 plugins 块 + settings.gradle.kts 统一声明插件版本
Gradle 7.0+ 推荐用 pluginManagement 块在 settings.gradle.kts 中集中配置插件版本,而不是在每个模块的 build.gradle.kts 里重复写 id("com.android.application") version "8.7.0"。这样能确保所有子项目加载的插件版本完全一致,避免因局部覆盖导致的构建行为差异。
常见错误现象:某个 module 升级了 android Gradle Plugin (AGP) 到 8.7.0,但其他 module 还在用 8.5.0,结果 assembleDebug 成功,lint 或 test 却报 Unsupported plugin version —— 实际上不是插件不兼容,而是多个 AGP 版本混用触发了内部校验失败。
-
settings.gradle.kts中必须放在最顶部(在include之前) - 版本号必须写死,不能用变量或
${}插值(Gradle 在解析pluginManagement阶段尚未加载任何项目属性) - 如果用了 Kotlin DSL,
plugins块里的id必须带引号,如id("org.jetbrains.kotlin.android")
pluginManagement {
plugins {
id("com.android.application") version "8.7.0"
id("com.android.library") version "8.7.0"
id("org.jetbrains.kotlin.android") version "1.9.24"
id("org.jetbrains.kotlin.jvm") version "1.9.24"
id("org.jetbrains.kotlin.plugin.serialization") version "1.9.24"
id("com.google.devtools.ksp") version "1.9.24-1.0.20"
}
}
为什么不用 buildSrc 或 ext 管理插件版本
插件版本不是普通依赖,它在构建生命周期早期就被解析和应用,而 buildSrc 和 ext 是在项目配置阶段才生效。把插件版本定义在 buildSrc/Version.kt 或根 build.gradle.kts 的 ext 里,会导致 IDE 无法识别、gradle plugin list 查不到真实版本,甚至在 CI 上出现「找不到插件」的静默失败。
典型场景:你在 buildSrc 里写了 const val agpVersion = "8.7.0",然后在 module 里写 id("com.android.application") version Versions.agpVersion —— Gradle 构建会直接报错 Plugin [id: 'com.android.application', version: 'Versions.agpVersion'] was not found,因为此时 Versions 类根本没被加载。
- 插件版本必须在
pluginManagement或plugins块中硬编码或通过versionCatalog引用(见下一条) -
buildSrc只适合管理普通库依赖(如implementation)、任务逻辑或自定义函数,不参与插件解析流程 - 用
gradle.properties定义agp.version=8.7.0同样无效:Gradle 不支持在pluginManagement中读取 properties
配合 versionCatalog 管理插件 ID 与版本分离
如果你希望把插件 ID 和版本拆开(比如统一用 libs.plugins.android.application 而不是硬写 com.android.application),得启用 VERSION_CATALOGS 并在 libs.versions.toml 中定义插件条目。但注意:这不是所有插件都支持,目前仅限于“可插件化”的插件(即发布时声明了 pluginBundle 的)。
容易踩的坑是误以为所有插件都能这么写。比如你加了 android-app = { id = "com.android.application", version.ref = "agp" },但同步时提示 Cannot resolve plugin android-app —— 因为 AGP 没有以标准方式发布插件元数据,它只支持直接 id("com.android.application")。
- 只对明确支持 Catalog 的插件使用此方式,例如
kotlin-android、ksp、dokka - AGP、
google-services、firebase-crashlytics等 Google 官方插件仍需在pluginManagement中硬写id和version -
libs.versions.toml中插件定义格式必须是[plugins.xxx],不是[libraries.xxx]
多项目中禁用子项目插件自动推断
默认情况下,Gradle 会根据 build.gradle.kts 中的 plugins 块自动推断插件版本,如果子项目没显式声明版本,就可能 fallback 到 Gradle 自带的默认版本(比如 AGP 8.4.0),造成和父项目不一致。
解决方法是在 settings.gradle.kts 的 pluginManagement 中加上 resolutionStrategy 强制约束:
pluginManagement {
resolutionStrategy {
// 禁止任何未声明版本的插件被加载
eachPlugin {
if (requested.id.namespace == "com.android") {
useVersion("8.7.0")
}
if (requested.id.namespace == "org.jetbrains.kotlin") {
useVersion("1.9.24")
}
}
}
}
这个配置比单纯列 plugins 更严格:即使某个 module 忘记写 version,也会被强制设为指定值,而不是让 Gradle 自行决定。但要注意,它只对命名空间匹配的插件生效,所以得提前知道插件 ID 的前缀模式。
真正复杂的地方在于,AGP 和 Kotlin 插件的版本强耦合,AGP 8.7.0 要求 Kotlin 1.9.24,但这个约束不会自动传递——你得自己查文档配对,漏掉就会在 compileKotlin 阶段卡住,报错信息还特别模糊,比如 Unresolved reference: kotlin,实际原因只是版本不匹配。











