3、Android Gradle Plugin(AGP)初探:AGP版本与Gradle版本对应关系、apply plugin机制、android {} 配置块详解
好,咱们今天来聊聊 AGP。Android Gradle Plugin,说白了就是 Google 为 Android 项目定制的 Gradle 插件。没有它,你的 .java 和 .kt 文件就变不成 APK。我刚开始接触 Android 构建时,总觉得这玩意儿就是个黑盒,点一下 Run 就完事了。后来踩了不少坑,才明白理解 AGP 是掌控构建流程的第一步。
3.1 AGP 版本与 Gradle 版本对应关系
这是最基础,也是最容易出问题的地方。AGP 和 Gradle 不是独立发展的,它们之间有严格的版本匹配关系。用错了,项目直接报错,连 Sync 都过不去。
为什么会这样?因为 AGP 内部依赖了 Gradle 的特定 API。Gradle 版本升级,API 可能变了,老版本的 AGP 就不认识了。
我个人习惯,每次创建新项目时,先去查一下官方兼容性表格。嗯,这里我直接给你整理了一份常用的对应关系:
| AGP 版本 | 最低 Gradle 版本 | 推荐 Gradle 版本 |
|---|---|---|
| 8.7 | 8.9 | 8.9+ |
| 8.6 | 8.7 | 8.7+ |
| 8.5 | 8.7 | 8.7+ |
| 8.4 | 8.6 | 8.6+ |
| 8.3 | 8.4 | 8.4+ |
| 8.2 | 8.2 | 8.2+ |
| 8.1 | 8.0 | 8.0+ |
| 8.0 | 8.0 | 8.0+ |
| 7.4 | 7.5 | 7.5+ |
| 7.3 | 7.4 | 7.4+ |
你可以在项目的 gradle/wrapper/gradle-wrapper.properties 文件中看到当前使用的 Gradle 版本:
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
而 AGP 版本则在项目的根 build.gradle 或 build.gradle.kts 中声明:
// Groovy (build.gradle)
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.7.0'
}
}
// Kotlin DSL (build.gradle.kts)
buildscript {
dependencies {
classpath("com.android.tools.build:gradle:8.7.0")
}
}
3.2 apply plugin 机制
AGP 本身是一个 Gradle 插件。要使用它,你得通过 apply plugin 把它应用到你的模块中。这就像给项目装上一个“Android 能力”的开关。
你想想看,一个项目里可能有多个模块,有的模块是 Android 应用,有的是 Android 库,还有的是纯 Java 库。每个模块需要的能力不同,所以应用的插件也不同。
常见的插件 ID 有:
com.android.application—— 用于应用模块,生成 APKcom.android.library—— 用于库模块,生成 AARcom.android.test—— 用于测试模块com.android.dynamic-feature—— 用于动态功能模块
在 Groovy 中,我们这样写:
// 应用 Android 应用插件
apply plugin: 'com.android.application'
// 或者应用 Android 库插件
apply plugin: 'com.android.library'
在 Kotlin DSL 中,写法稍有不同,但意思一样:
// 应用 Android 应用插件
plugins {
id("com.android.application")
}
// 或者应用 Android 库插件
plugins {
id("com.android.library")
}
plugins {} 块的方式。它比 apply plugin 更安全,能帮你提前检测到插件版本冲突。而且 Kotlin DSL 下,plugins {} 是标准写法。
这里有个细节:apply plugin 是立即执行的,而 plugins {} 块是声明式的,Gradle 会在配置阶段统一处理。所以,如果你在 plugins {} 块里写错了插件 ID,Gradle 会直接报错,而不是等到执行时才报。这能帮你早点发现问题。
3.3 android {} 配置块详解
应用了 AGP 插件后,你的模块就有了 android {} 这个配置块。这是整个构建配置的核心,所有 Android 相关的设置都在这里。
我刚开始看这个配置块时,觉得它又长又乱。后来慢慢理清了结构,发现其实很有条理。咱们来拆解一下:
android {
// 1. 编译配置
compileSdk 34
buildToolsVersion "34.0.0"
ndkVersion "25.2.9519653"
// 2. 默认配置
defaultConfig {
applicationId "com.example.myapp"
minSdk 21
targetSdk 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
// 3. 构建类型
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix ".debug"
debuggable true
}
}
// 4. 产品风味(多渠道打包)
flavorDimensions "version", "api"
productFlavors {
demo {
dimension "version"
applicationIdSuffix ".demo"
}
full {
dimension "version"
applicationIdSuffix ".full"
}
minApi21 {
dimension "api"
minSdk 21
}
minApi24 {
dimension "api"
minSdk 24
}
}
// 5. 编译选项
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
// 6. Kotlin 选项
kotlinOptions {
jvmTarget = "17"
}
// 7. 打包选项
packaging {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
// 8. 动态功能模块
dynamicFeatures = [":feature1", ":feature2"]
}
咱们挑几个重点说说:
3.3.1 compileSdk 与 targetSdk
compileSdk 告诉 Gradle 用哪个版本的 Android API 来编译代码。你用了新 API,就得把 compileSdk 升上去。但注意,它不影响运行时的行为。
targetSdk 则告诉系统:我这个应用是为哪个 API 级别设计的。系统会根据这个值来决定是否启用一些兼容性行为。比如,Android 10 开始强制要求 targetSdk >= 29,否则会弹出警告。
compileSdk 始终使用最新稳定版,targetSdk 则根据你的测试进度逐步升级。不要盲目升 targetSdk,否则可能引入新的权限或行为变更。
3.3.2 buildTypes 与 productFlavors
buildTypes 是构建类型,默认有 debug 和 release。你可以自定义更多,比如 staging、beta 等。
productFlavors 是产品风味,用于多渠道打包。比如免费版、付费版,或者不同渠道的定制包。
这两者组合起来,就形成了 Build Variant(构建变体)。比如 demoDebug、fullRelease 等。每个变体都可以有自己的配置。
3.3.3 compileOptions 与 kotlinOptions
这两个配置块用于设置 Java 和 Kotlin 的编译版本。现在主流是 Java 17,Kotlin 的 JVM 目标也设为 17。如果你用 Java 8 的语法,但 sourceCompatibility 设成了 17,Gradle 会允许你使用 Java 17 的语法特性,但生成的字节码还是 Java 8 兼容的。
嗯,这里要注意:compileOptions 和 kotlinOptions 必须保持一致,否则 Kotlin 编译可能会报错。
3.4 知识体系总览
说了这么多,咱们用一张图来总结一下 AGP 的核心知识体系:
这张图把 AGP 的核心分成了三大块:版本对应关系、插件应用机制、以及 android {} 配置块。每一块都有它的作用,缺一不可。
compileSdk、minSdk、targetSdk 和 buildTypes 这几个最常用的。其他的,用到时再查文档。我曾经花了一周时间背配置项,结果发现根本记不住,还不如多写几个项目来得实在。
好了,AGP 的初探就到这里。记住,版本匹配是基础,插件应用是入口,android {} 配置块是核心。把这三点理清了,后面的路就好走了。
公众号:蓝海资料掘金营,微信deep3321