这篇文章主要带你探索 Gradle 的核心技术,用通俗的例子讲透 Gradle 构建流程、Project 和 Task 的使用技巧,以及如何自定义任务插入到 Android 构建流程中。以下是核心内容总结:
一、Gradle 构建的三阶段 “流水线”
-
初始化阶段:
就像开工前的准备会议,Gradle 会先执行settings.gradle,确定要构建哪些模块(比如 app 模块),并为每个模块创建对应的 Project 对象。- 例子:
include ':app'就是告诉 Gradle “我要构建 app 模块”。
- 例子:
-
配置阶段:
相当于制定详细的施工计划,Gradle 会解析每个模块的build.gradle,构建任务依赖图(比如编译代码、打包 APK 的任务顺序)。- 注意:这里会执行除了 Task 具体动作外的所有代码,比如变量定义、插件引用。
-
执行阶段:
真正开始干活,按顺序执行任务(Task)。比如先编译 Java 代码,再打包资源,最后生成 APK。- 例子:执行
./gradlew build时,Gradle 会按依赖图依次运行compileDebugJavaWithJavac、assembleDebug等任务。
- 例子:执行
二、Gradle 生命周期:每个阶段的 “闹钟提醒”
Gradle 在每个阶段都提供了回调钩子,就像闹钟一样提醒你在特定时刻做事情:
-
初始化完成后:
gradle.projectsLoaded -
配置每个模块前:
gradle.beforeProject -
配置每个模块后:
gradle.afterProject -
任务执行前:
gradle.taskGraph.beforeTask -
所有任务完成后:
gradle.buildFinished
应用场景:用这些钩子打印构建耗时,比如计算从初始化到执行完成的总时间,定位性能瓶颈。
三、Project 对象:模块的 “指挥官”
每个build.gradle对应一个 Project 对象,它负责管理模块的所有配置:
-
常用功能:
- 获取项目路径:
getRootDir()(根目录)、getBuildDir()(构建输出目录) - 引用插件:
apply plugin: 'com.android.application' - 管理依赖:
dependencies { implementation 'xxx:xxx' }
- 获取项目路径:
-
扩展属性:全局共享的 “便利贴”
在build.gradle或gradle.properties中定义全局变量,比如:groovy
ext { androidConfig = [compileSdkVersion: 30, targetSdkVersion: 30] }好处是统一管理版本号、依赖库,避免重复代码。
四、Task:Gradle 的 “最小工作单元”
Task 是 Gradle 执行的最小任务,比如 “编译代码”“拷贝文件”“清理构建产物”:
-
Task 的 “动作时机” :
doFirst:任务开始时执行doLast:任务结束时执行
groovy
task cleanApk { doLast { delete "app/build/outputs/apk" // 执行时删除APK文件 } } -
Task 依赖管理:任务的 “先后顺序”
dependsOn:强依赖,比如taskB dependsOn taskA表示先执行 taskA 再执行 taskBmustRunAfter:指定执行顺序,但不强制依赖finalizedBy:任务完成后执行另一个任务,比如taskA finalizedBy taskB表示 taskA 完成后执行 taskB
-
Task 类型:现成的 “工具包”
Gradle 自带多种 Task 类型,比如:Copy:拷贝文件Delete:删除文件JavaCompile:编译 Java 代码
五、自定义 Task 插入 Android 构建流程
想在 Android 构建过程中插入自己的任务?有三种方法:
-
依赖绑定:让系统任务依赖你的任务
groovy
task myTask { doLast { println "我在打包前执行" } } tasks.findByName("mergeDebugResources").dependsOn(myTask) // 合并资源前执行myTask -
后置执行:系统任务完成后执行你的任务
groovy
tasks.findByName("assembleDebug").finalizedBy(myTask) // 打包完成后执行myTask -
顺序插入:在两个系统任务之间插入你的任务
groovy
myTask.mustRunAfter(tasks.findByName("mergeDebugResources")) tasks.findByName("processDebugResources").dependsOn(myTask)
六、实用命令:Gradle 的 “快捷操作”
./gradlew tasks:查看所有任务./gradlew app:dependencies:查看模块依赖关系./gradlew build taskTree --no-repeat:查看任务依赖图
总结
这篇文章带你从 Gradle 的构建流程入手,学会了如何用 Project 管理模块配置、用 Task 定义具体任务,以及如何通过生命周期钩子和依赖管理将自定义任务插入到 Android 构建流程中。这些知识是自定义 Gradle 插件、优化构建流程的基础,后续还可以进一步探索 Transform、代码混淆等高级功能。