一、第一原则

优先使用AI实现和修复Gradle配置问题

二、Gradle和AGP基本概念

  1. Gradle是通用的自动化构建工具,提供基础的构建框架(依赖管理、任务编排),可用于各种构建场景,不局限于Android构建。

  2. AGP是Android Gradle Plugin的缩写,是专门为Android开发设计的Gradle插件。

    • com.android.tools.build:gradle:版本号是AGP本身在代码仓库中的Maven坐标,用于安装整个AGP工具箱。

    • AGP工具箱中常用插件:com.android.applicationcom.android.library

    • 依赖方式:旧版:项目根目录的build.gradle中,通过classpath依赖显式声明。新版方式:在plugins代码块中通过idversion声明后,Gradle会自动在后台处理这个坐标的解析,无需手动通过classpath显式生命依赖。

三、常见plugin插件的功能

插件名称 功能 备注
com.android.application 打包APK,包含android{}、dependencies{}、buildTypes{}等常用的闭包 AGP核心插件
com.android.library 打包AAR,包含android{}、dependencies{}等常用闭包,及部分library独有闭包。 AGP核心插件
com.android.kotlin.multiplatform.library 官方为KMP项目提供的插件,用于替代标准的库插件,对KMP场景做了专门优化 AGP核心插件
org.jetbrains.kotlin.android
别名: kotlin-android
Kotlin官方插件, 用于在Android项目(app、library)中编译Kotlin文件。 Android项目
java-gradle-plugin 1. 官方核心插件,自动应用 java-library 插件并添加 Gradle API 依赖(gradleApi()
2. 同时也会自动生成插件描述符,resources/META-INF/gradle-plugins/
自定义Gradle插件
kotlin-dsl 1. 用于Kotlin编写插件,编译.kts文件。只能在.kts文件中引用,不能在.gradle文件中引用。
2. 自动应用java-gradle-pluginembedded-kotlin插件
3. 无需指定版本,与Gradle版本严格绑定
自定义Gradle插件
org.jetbrains.kotlin.jvm
别名:kotlin(“jvm”)
编译.kt文件,用于自定义Gradle插件、纯jvm项目。不支持Android(apk、library)编译 自定义Gradle插件
gradle-build-timer-plugin
别名:gradle-profiler
构建耗时分析工具,用于定位构建瓶颈 Gradle效率工具
dexcount-gradle-plugin APK方法数统计插件,帮助监控方法数,避免触及64K方法数限制 Gradle效率工具

四、自定义插件模块

1. 插件的module目录build.gradle.kts文件

// 插件项目版本(发布到仓库后,其他项目引用时使用的版本)
version = "1.0.0"
group = "com.example.asm"

plugins {
    id("java-gradle-plugin") // java-gradle-plugin: Gradle 插件开发插件,提供 gradlePlugin DSL 配置块
    kotlin("jvm") version "1.8.10" // kotlin("jvm"): Kotlin JVM 支持,用于编译 Kotlin 代码
    id("maven-publish") // maven-publish: 用于发布 Maven 仓库的插件
}

// 插件声明配置
gradlePlugin {
    plugins {
        // 创建一个插件声明,"asmMethodTimeCost" 是内部标识名,起什么名字都可以
        create("asmMethodTimeCost") {
            // 插件 ID: 在其他模块中使用这个插件时引用的 ID
            // 用法: plugins { id("com.example.asm.test") version "1.0.0" }
            id = "com.example.asm.test"

            // 插件实现类的完整路径(包名 + 类名)
            // 必须实现 org.gradle.api.Plugin<Project> 接口
            implementationClass = "com.example.asm.test.AsmPlugin"

            // 插件显示名称和描述(发布到 Gradle Plugin Portal 时使用)
            displayName = "ASM Method Time Cost Plugin"
            description = "A Gradle plugin to measure method execution time using ASM"
            tags.set(listOf("asm", "android", "bytecode", "performance"))
        }
    }
}

dependencies {
    // gradleApi(): Gradle 核心 API,提供 Plugin、Project、Task 等基础接口
    implementation(gradleApi())

    // Android Gradle Plugin API: 访问 Android 编译流程,提供BaseVariant、Transform 等接口
    implementation("com.android.tools.build:gradle-api:7.4.2")
    // 非必须,这是 AGP 内部实现,除非访问未公开的内部API
    implementation("com.android.tools.build:gradle:7.4.2")

    // ASM 字节码操作库
    implementation("org.ow2.asm:asm:9.4")
    implementation("org.ow2.asm:asm-commons:9.4")
}

2. 插件入口类定义

package com.example.asm.test

import org.gradle.api.Plugin
import org.gradle.api.Project

class AsmMethodTimeCostPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        // TODO: 实现插件逻辑
    }
}

3. 插件描述符文件

  • 使用 java-gradle-plugin自动生成,根据build.gradle.kts中的gradlePlugin{}闭包中的参数自动生成。
  • 文件路径和命名遵循严格约定,位于 JAR 包内的 META-INF/gradle-plugins/ 目录,并以 <插件ID>.properties 的格式命名。
  • 使用者可以直接 plugins { id("com.example.asm.test") }的方式引用
  • 文件名称:com.example.asm.test.properties
implementation-class=com.example.asm.test.AsmMethodTimeCostPlugin

4. 插件发布

  • 在build.gradle.kts文件中引用maven-publish插件,并且声明versiongroup字段
  • 执行如下命令,发布插件后,就可以在其他模块(app、library)中使用插件id进行引用。
  • 插件发布路径由mavenLocal()函数定义,mac电脑一般是~/.m2/repository/
 ./gradlew :asmtestplugin:publishToMavenLocal

5. 插件文件格式

  • 插件的产物是jar包,例如asmtestplugin-1.0.0.jar

6. 工程内插件依赖方式

  • 可以在app模块build.gradle中直接指定插件的类文件(插件入口)进行直接依赖
  • 插件修改后还是需要使用 ./gradlew :asmtestplugin:publishToMavenLocal重新发布才能生效
 apply plugin: com.example.asm.test.AsmPlugin   

五、Groovy和 Kotlin DSL语法

1. 背景

  • Kotlin DSL现在已是 Gradle 官方默认推荐语言。
  • Groovy DSL:动态语言,大量利用“方法调用省略括号”“属性自动生成 getter/setter”“元编程”等技巧,写起来更像自然语言,但 IDE 支持弱,出错往往在运行时报错。
  • Kotlin DSL:静态类型,所有调用都有明确类型约束,IDE 能给出精确的代码提示和重构支持,编译阶段就能发现大部分错误,代价是语法更严谨、括号和引号不可省略。

2. 主要差异

  • 无论是Groovy DSL还是Kotlin DSL,都兼容id("java")格式。
场景 Groovy DSL Kotlin DSL
文件名称 .gradle .gradle.kts
字符串 单/双引号均可 'java'或者"java" 字符串必须双引号 "java",单引号是 Char
引号使用 双引号+括号:id(“java”)
单引号:id ‘java’
双引号:id “java”
反引号:不支持
不带任何引号:不支持
双引号+括号:id(“java”)
单引号:不支持
双引号:id “java”
反引号:`kotlin-dsl` // 带-必须使用反引号
不带任何引号:java // 这类是官方的属性扩展
方法调用 括号可省略 id 'java' 括号必须 id("java")

3. Kotlin DSL中使用等号赋值,使用括号进行函数调用怎么区分?

  • 首选方法:看 IDE 自动补全(IntelliJ IDEA / Android Studio)

  • 如果补全提示里是 property 标记(或直接显示类型,如 String),那就是属性,用 = 赋值。

  • 如果提示里是 fun 标记,那就是函数,用 () 调用。

六、其他

1. buildSrc目录

  • buildSrc是 Gradle 项目根目录下的一个特殊模块,专门存放构建逻辑代码。只要目录存在,Gradle 就会自动把这个目录当作一个独立的子项目来编译,并把编译好的类自动加到整个项目的构建脚本 classpath 中。你可以在里面写自定义插件、任务、扩展,然后在根项目的 build.gradle(.kts) 里直接使用。
  • 它是自动识别的,buildSrc是项目的保留字段。Gradle 的生命周期中,一但检测到 buildSrc 目录,会:
    1. 将其编译为 jar;
    2. 把 jar 和其依赖放到构建脚本的 classpath
    3. 在所有模块的 build.gradle.kts可直接引用 buildSrc 里定义的类或对象,无需任何 classpath 声明。

2. gradlePluginPortal()

  • Plugin插件专属的仓库。在项目根目录repositories{}闭包中配置。
Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐