Gradle 与 AGP:不只是调用关系
说实话,很多刚接触 Android 的朋友会把 Gradle 和 AGP 混为一谈。我之前带新人时就发现,配置文件里一行 id 'com.android.application',他们以为 "这就是 Gradle 本身"。其实不是的。
Gradle 是个通用的构建工具,它不知道什么叫 Android、什么叫 APK。真正让 Gradle 懂 Android 的,是 AGP —— Android Gradle 插件。AGP 就是一个 Gradle 插件,它把 Android 的编译、打包、签名等逻辑「注入」到 Gradle 的构建流程里。
通过 Gradle 插件集成 AGP
集成 AGP 的方式,说白了就两种。我习惯用新版的 plugins 块,简洁且支持版本锁定:
// settings.gradle.kts
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
// app/build.gradle.kts
plugins {
id("com.android.application") version "8.2.2" apply false
}
// app/build.gradle.kts
plugins {
id("com.android.application")
}
如果你还在用老项目,可能看到的是这种写法:
// app/build.gradle
buildscript {
repositories {
google()
}
dependencies {
classpath "com.android.tools.build:gradle:8.2.2"
}
}
apply plugin: "com.android.application"
哪种更好?我个人推荐 plugins 块。原因是它可以避免许多依赖冲突问题。我记得有次帮同事排查构建问题,他用的是旧式的 apply plugin,结果项目里两个子模块引了不同版本的 AGP,直接炸了——编译都过不去。换成 plugins 块统一声明后,问题就解决了。
settings.gradle.kts 里把 google() 仓库放在第一位。AGP 和 AndroidX 的依赖都从 Google 的 Maven 仓库拉,顺序不对很容易卡网络或报 404。
版本兼容性——最容易踩坑的地方
AGP 和 Gradle 的版本是有严格对应关系的。不是说你用最新的 AGP 就行,还得看你的 Gradle 版本是否支持。我曾经在项目里直接把 AGP 从 7.0 跳到 8.2,没改 Gradle wrapper 版本,结果编译报错提示 API 不兼容。折腾了半天才发现 Gradle 版本太低。
下面这张表格是我从历年升级中整理出来的「AGP - Gradle 版本对应表」,有些公司内部的基线会用这些组合:
| AGP 版本 | 最低 Gradle 版本 | 推荐 Gradle 版本 | 备注 |
|---|---|---|---|
| 8.3.x | 8.4 | 8.5+ | 支持 Java 17 编译 |
| 8.2.x | 8.2 | 8.4 | 稳定版,推荐升级 |
| 8.1.x | 8.0 | 8.2 | 旧项目过渡用 |
| 8.0.x | 8.0 | 8.1 | 最低要求 Gradle 8.0 |
| 7.4.x | 7.5 | 7.6 | 部分老库仍用此版本 |
| 7.3.x | 7.4 | 7.5 | 注意 NDK 兼容 |
怎么知道当前项目该用哪个 AGP?
我的做法是两步走:
- 查 Gradle 版本: 运行
./gradlew --version,或者看gradle/wrapper/gradle-wrapper.properties里的distributionUrl。 - 查 AGP 版本: 看项目根目录
build.gradle或settings.gradle里声明的com.android.tools.build:gradle版本号。
然后对照上面的表格,就能知道当前组合是否合法。举个例子,如果你发现自己的 Gradle 是 7.6,AGP 是 8.1,那就要小心了——7.6 其实不满足 8.1 的 Gradle 最低要求(8.0)。虽然有时低版本 Gradle 也能勉强运行 AGP 8.1,但你会遇到各种诡异的缓存错误,比如 R 资源找不到、BuildConfig 不生成之类。我在升级 AGP 8.2 时就被这种问题坑过,后来严格按表格走,再没出现类似情况。
知识结构速览
下面这张图是我自己总结的「Gradle ↔ AGP ↔ SDK 调用链路」,能帮你快速理清它们之间的关系:
从这张图能看出来,AGP 处于中间枢纽位置:上面通过 plugins 或 apply plugin 被 Gradle 加载,下面同时依赖 Android SDK 和 Gradle API 的版本。任何一个不匹配,都会导致构建失败。我之前在升级到 AGP 8.2 时就忘了升级 Gradle 到 8.2,结果 SDK 工具链报了一大堆 "API level 34 not supported" —— 其实根本不是 SDK 的问题,是 Gradle 版本太老,AGP 8.2 用了一个它不认识的 API。
避坑指南:升级三步曲
如果你现在正准备给项目升级 AGP,我的建议是:
- 第一步: 确认当前 Gradle 版本,在官方兼容性矩阵中找到对应的最高 AGP 版本(不要直接跳大版本,比如从 7.0 直接到 8.3,最好 7.4 → 8.0 → 8.2 逐步升级)。
- 第二步: 修改
gradle-wrapper.properties里的 Gradle 版本到推荐值,执行./gradlew wrapper --gradle-version 8.4更新 wrapper。 - 第三步: 修改
plugins或buildscript中的 AGP 版本号,然后./gradlew clean后全量构建。
lint 插件和 kapt 全都报 ClassNotFoundException,浪费了一整天排查。老老实实按表格升,反而最快。
总结一下重点
- AGP 是一个 Gradle 插件,通过
plugins块集成到 Gradle 里。 - 每个 AGP 版本有对应的最低 Gradle 版本要求,不满足则无法编译。
- 升级时优先看官方兼容表,同步升级 Gradle wrapper,而不是只改 AGP 版本号。
- 推荐使用新版
plugins声明方式,避免旧式apply plugin的依赖混乱问题。
嗯,核心就这些。下个阶段我们就要真正动手画瀑布图了——不过前提是你已经能把 Gradle 和 AGP 的关系理顺。搞不定兼容性的话,后边的所有性能分析都没法跑。所以别嫌这章啰嗦,基础打牢了才能走远。