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+
⚠️ 注意: 我曾经在升级 AGP 8.2 时,忘了同步升级 Gradle Wrapper,结果项目直接报错 "The Android Gradle plugin requires Java 17"。折腾了半天才发现是 Gradle 版本太低。所以,升级 AGP 时,一定要同步检查 Gradle 版本和 JDK 版本。

你可以在项目的 gradle/wrapper/gradle-wrapper.properties 文件中看到当前使用的 Gradle 版本:

distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip

而 AGP 版本则在项目的根 build.gradlebuild.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 —— 用于应用模块,生成 APK
  • com.android.library —— 用于库模块,生成 AAR
  • com.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 是构建类型,默认有 debugrelease。你可以自定义更多,比如 stagingbeta 等。

productFlavors 是产品风味,用于多渠道打包。比如免费版、付费版,或者不同渠道的定制包。

这两者组合起来,就形成了 Build Variant(构建变体)。比如 demoDebugfullRelease 等。每个变体都可以有自己的配置。

3.3.3 compileOptions 与 kotlinOptions

这两个配置块用于设置 Java 和 Kotlin 的编译版本。现在主流是 Java 17,Kotlin 的 JVM 目标也设为 17。如果你用 Java 8 的语法,但 sourceCompatibility 设成了 17,Gradle 会允许你使用 Java 17 的语法特性,但生成的字节码还是 Java 8 兼容的。

嗯,这里要注意:compileOptionskotlinOptions 必须保持一致,否则 Kotlin 编译可能会报错。

3.4 知识体系总览

说了这么多,咱们用一张图来总结一下 AGP 的核心知识体系:

AGP 核心知识体系 Android Gradle Plugin AGP 版本 ↔ Gradle 版本对应关系 gradle-wrapper.properties build.gradle 中的 classpath apply plugin 机制 com.android.application com.android.library plugins {} 块 vs apply plugin android {} 配置块 compileSdk / targetSdk buildTypes + productFlavors compileOptions / kotlinOptions packaging / dynamicFeatures 掌握这三块,AGP 基本就入门了

这张图把 AGP 的核心分成了三大块:版本对应关系、插件应用机制、以及 android {} 配置块。每一块都有它的作用,缺一不可。

💡 我的经验: 刚开始学 AGP 时,别想着一次性记住所有配置项。先掌握 compileSdkminSdktargetSdkbuildTypes 这几个最常用的。其他的,用到时再查文档。我曾经花了一周时间背配置项,结果发现根本记不住,还不如多写几个项目来得实在。

好了,AGP 的初探就到这里。记住,版本匹配是基础,插件应用是入口,android {} 配置块是核心。把这三点理清了,后面的路就好走了。


公众号:蓝海资料掘金营,微信deep3321