破解Gradle Gradle构建生命周期
Posted 丶笑看退场
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了破解Gradle Gradle构建生命周期相关的知识,希望对你有一定的参考价值。
android Studio默认的工具是Gradle,通常开发者不需要了解Gradle的脚本配置,也能开发出一个App,但是如果你需要修改打包中的输出目录、提高打包速度的话,就要对Gradle有个深入的了解了。而在开发学习Gradle不能仅仅把它当做一个工具来学习,更应该把它当成编程框架来看,这里是Gradle API文档,我们再编写编译脚本,其实就是在玩 Gradle的API。
Gradle的组成可以分为三部分:
- groovy核心语法
- Build script block
- Gradle API:包含project、Task/Settiing等等,也是接下来重点介绍的。
Gradle优势
- 在灵活性上,Gradle支持基于groovy语言编写脚本,侧重于构建过程的灵活性,适合于构建复杂度较高的项目,可以完成非常复杂的构建。
- 在粒度性上,Gradle 构建的粒度细化到了每一个 task 之中。并且它所有的 Task 源码都是开源的,在我们掌握了这一整套打包流程后,我们就可以通过去修改它的 Task 去动态改变其执行流程。
- 在扩展性上,Gradle 支持插件机制,所以我们可以复用这些插件,就如同复用库一样简单方便。
Grale 构建生命周期
下面来看下gradle的执行命令,执行./gradlew build
可以说是最复杂的task命令了。 (./gradlew是mac中的语法)
可以看到每次都会执行很长时间,是因为build的task任务依赖了很多任务,它会把它所依赖的task执行完之后,才会执行自己的task.。我们还是先了解下Gradle的构建过程。
Gradle的构建过程可以分为三部分:初始化阶段、配置阶段和执行阶段。
初始化阶段
Gradle为每个项目创建一个Project实例,在多项目构建中,Gradle会找出哪些项目依赖需要参与到构建中。与初始化相关的的脚本是settings.gradle
,会读出整个工程中有多少个project.
配置阶段
配置阶段的任务是执行各项目下的build.gradle脚本,完成Project配置,并且构造Task任务依赖关系图以便在执行阶段按照依赖关系执行Task。
每个build.gradle
对应一个Project
对象,配置阶段执行的代码包括build.gralde
中的各种语句、闭包以及Task
中的配置段语句。
执行阶段
在配置阶段结束后,Gradle会根据任务Task的依赖关系会创建一个有向无环图,还可以通通过Gradle对象的getTaskGraph方法访问,对应的类是TaskExecutionGraph,然后通过调用gradle <任务>执行对应任务。
Gradle生命周期监听
Project中添加生命周期监听
现在我们来看下平时开发中最常用的监听方法:
//在 Project 进行配置前调用
void beforeEvaluate(Closure closure)
//在 Project 配置结束后调用
void afterEvaluate(Closure closure)
接下来用个例子来验证下结果:
setting.gradle
include ':app'
println '初始化阶段开始...'
根目录下的build.gradle
//对子模块进行配置
subprojects sub ->
sub.beforeEvaluate proj ->
println "子项目beforeEvaluate回调..."
println "根项目配置开始---"
task rootTest
println "根项目里任务配置---"
doLast
println "执行根项目任务..."
println "根项目配置结束---"
app目录下的build.gradle
println "APP子项目配置开始---"
afterEvaluate
println "APP子项目afterEvaluate回调..."
task appTest
println "APP子项目里任务配置---"
doLast
println "执行子项目任务..."
println "APP子项目配置结束---"
执行下`./gradlew clean,得到如下的打印结果:
初始化阶段开始...
根项目配置开始---
根项目里任务配置---
根项目配置结束---
子项目beforeEvaluate回调...
APP子项目配置开始---
APP子项目里任务配置---
APP子项目配置结束---
APP子项目afterEvaluate回调...
Gradle中添加生命周期监听
在setting.gradle
中添加:
include ':app'
gradle.addBuildListener(new BuildListener()
//构建开始前调用
void buildStarted(Gradle var1)
println '构建开始...'
//settings.gradle配置完后调用,只对settings.gradle设置生效
void settingsEvaluated(Settings var1)
// var1.gradle.rootProject 这里访问 Project 对象时会报错,
// 因为还未完成 Project 的初始化。
println 'settings:执行settingsEvaluated...'
//当settings.gradle中引入的所有project都被创建好后调用,只在该文件设置才会生效
void projectsLoaded(Gradle var1)
println 'settings:执行projectsLoaded...'
println '初始化结束,可访问根项目:' + var1.gradle.rootProject
//所有project配置完成后调用
void projectsEvaluated(Gradle var1)
println 'settings: 执行projectsEvaluated...'
//在project进行配置前调用,child project必须在root project中设置才会生效,root project必须在settings.gradle中设置才会生效
void beforeProject proj ->
println "settings:执行$proj.name beforeProject"
//在project配置后调用
void afterProject proj ->
println "settings:执行$proj.name afterProject"
//构建结束后调用
void buildFinished(BuildResult var1)
println '构建结束 '
)
看下输出结果:
settings:执行settingsEvaluated...
settings:执行projectsLoaded...
settings:执行GradleTestDemo beforeProject
根项目配置开始---
根项目里任务配置---
根项目配置结束---
settings:执行GradleTestDemo afterProject
settings:执行app beforeProject
子项目beforeEvaluate回调...
APP子项目配置开始---
APP子项目里任务配置---
APP子项目配置结束---
settings:执行app afterProject
APP子项目afterEvaluate回调...
settings: 执行projectsEvaluated...
构建结束...
另外还有其他监听方法:
this.gradle.beforeProject //等同于beforeEvaluate
this.graddle.afterProject //等同于afterEvaluate
//下面几种都是可以监听的
this.gradle.addListener
tthis.gradle.addProjectEvaluationListener
在了解了gradle的生命周期监听后,还有个疑问为什么执行build命令的时候,会其他命令的输出。下面我们来看一张图:
这张图会在配置阶段完成,形成一个有向无环图,在执行名字为build的task的时候,所以会有其他依赖的task都要执行完。
TaskExecutionGraph(Task执行图)
Gradle 在配置完成后,会对所有的 task 生成一个有向无环图,这里叫做 task 执行图,他们决定了 task 的执行顺序等。
TaskExecutionGraph API文档
下面是常用的API方法:
API | 描述 |
---|---|
addTaskExecutionGraphListener | 给任务执行图添加监听 |
addTaskExecutionListener | 给任务的执行添加监听 |
whenReady | 当任务执行图填充完毕被调用 |
beforeTask | 当一个任务执行之前被调用 |
afterTask | 当一个任务执行完毕被调用 |
hasTask | 查询是否有这个task |
getAllTasks | 获取所有的Task |
Set getDependencies(Task task) | 返回参数Task的依赖关系 |
同样,Gradle 可以对 task 的执行生命周期进行监听。
TaskExecutionGraph taskGraph = gradle.getTaskGraph()
taskGraph.whenReady
println "task whenReady"
taskGraph.beforeTask Task task ->
println "任务名称:$task.name beforeTask"
taskGraph.afterTask Task task ->
println "任务名称:$task.name afterTask"
参考
深度探索 Gradle 自动化构建技术(三、Gradle 核心解密)
以上是关于破解Gradle Gradle构建生命周期的主要内容,如果未能解决你的问题,请参考以下文章
从Gradle生命周期到自定义Task挂接到Build构建流程全解
从Gradle生命周期到自定义Task挂接到Build构建流程全解
Android Gradle 插件Gradle 构建生命周期 ② ( Gradle 类的添加构建生命周期监听器函数 | Gradle#addListener 函数 )
Android Gradle 插件Gradle 构建机制 ④ ( Gradle 构建生命周期 | 初始阶段 | 配置阶段 | 执行阶段 )
Android Gradle 插件Gradle 构建生命周期 ① ( 分析构建脚本 | 执行初始化配置 | 执行 Gradle 任务 | Project#beforeEvaluate 函数 )