文章目录一、第一原则二、Gradle和AGP基本概念三、常见plugin插件的功能四、自定义插件模块1. 插件的module目录build.gradle.kts文件2. 插件入口类定义3. 插件描述符文件4. 插件发布5. 插件文件格式6. 工程内插件依赖方式五、Groovy和 Kotlin DSL语法1. 背景2. 主要差异3. Kotlin DSL中使用等号赋值使用括号进行函数调用怎么区分六、其他1. buildSrc目录2. gradlePluginPortal()一、第一原则优先使用AI实现和修复Gradle配置问题二、Gradle和AGP基本概念Gradle是通用的自动化构建工具提供基础的构建框架依赖管理、任务编排可用于各种构建场景不局限于Android构建。AGP是Android Gradle Plugin的缩写是专门为Android开发设计的Gradle插件。com.android.tools.build:gradle:版本号是AGP本身在代码仓库中的Maven坐标用于安装整个AGP工具箱。AGP工具箱中常用插件com.android.application、com.android.library等依赖方式旧版项目根目录的build.gradle中通过classpath依赖显式声明。新版方式在plugins代码块中通过id和version声明后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-androidKotlin官方插件, 用于在Android项目app、library中编译Kotlin文件。Android项目java-gradle-plugin1. 官方核心插件自动应用java-library插件并添加 Gradle API 依赖gradleApi()2. 同时也会自动生成插件描述符resources/META-INF/gradle-plugins/。自定义Gradle插件kotlin-dsl1. 用于Kotlin编写插件编译.kts文件。只能在.kts文件中引用不能在.gradle文件中引用。2. 自动应用java-gradle-plugin和embedded-kotlin插件3. 无需指定版本与Gradle版本严格绑定自定义Gradle插件org.jetbrains.kotlin.jvm别名kotlin(“jvm”)编译.kt文件用于自定义Gradle插件、纯jvm项目。不支持Androidapk、library编译自定义Gradle插件gradle-build-timer-plugin别名gradle-profiler构建耗时分析工具用于定位构建瓶颈Gradle效率工具dexcount-gradle-pluginAPK方法数统计插件帮助监控方法数避免触及64K方法数限制Gradle效率工具四、自定义插件模块1. 插件的module目录build.gradle.kts文件// 插件项目版本发布到仓库后其他项目引用时使用的版本version1.0.0groupcom.example.asmplugins{id(java-gradle-plugin)// java-gradle-plugin: Gradle 插件开发插件提供 gradlePlugin DSL 配置块kotlin(jvm)version1.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 }idcom.example.asm.test// 插件实现类的完整路径包名 类名// 必须实现 org.gradle.api.PluginProject 接口implementationClasscom.example.asm.test.AsmPlugin// 插件显示名称和描述发布到 Gradle Plugin Portal 时使用displayNameASM Method Time Cost PlugindescriptionA Gradle plugin to measure method execution time using ASMtags.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 内部实现除非访问未公开的内部APIimplementation(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. 插件入口类定义packagecom.example.asm.testimportorg.gradle.api.Pluginimportorg.gradle.api.ProjectclassAsmMethodTimeCostPlugin:PluginProject{overridefunapply(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.propertiesimplementation-classcom.example.asm.test.AsmMethodTimeCostPlugin4. 插件发布在build.gradle.kts文件中引用maven-publish插件并且声明version和group字段执行如下命令发布插件后就可以在其他模块app、library中使用插件id进行引用。插件发布路径由mavenLocal()函数定义mac电脑一般是~/.m2/repository/./gradlew:asmtestplugin:publishToMavenLocal5. 插件文件格式插件的产物是jar包例如asmtestplugin-1.0.0.jar6. 工程内插件依赖方式不想每次修改都需要发布可以在app模块build.gradle中直接指定插件的类文件插件入口进行直接依赖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 DSLKotlin 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目录会将其编译为 jar把 jar 和其依赖放到构建脚本的 classpath在所有模块的build.gradle.kts中可直接引用buildSrc里定义的类或对象无需任何classpath声明。2. gradlePluginPortal()Plugin插件专属的仓库。在项目根目录repositories{}闭包中配置。