大家好,又见面了,我是你们的朋友全栈君。
在前几篇中,讲解了Groovy的基础语法,学习新语法过程总是枯燥的,但为了更好的掌握Gradle,那就必须经过该过程。当然从这一篇将会从零基础开始,开展对Gradle的讲解。
CMD 命令窗口输入 gradle -v,看看是否显示当前Gradle版本
我们学习任何开发语言,第一个程序都离不开Hello 程序。所以仪式感还是要有的。
在工程文件夹下,创建一个build.gradle文件:
在文件里写入代码
task hello{
println 'Hello, Gradle!'
}
打开cmd终端,移动到工程目录下,执行命令:> gradle -q hello
最终效果
如图所示
当运行成功时,将会自动创建.gradle文件夹。
此时我们继续在这个命令窗口执行命令:gradle wrapper 将会看到
如图所示
在本目录里面,系统自动帮我们创建了一系列文件以及文件夹,这些文件都似曾相识,打开AS和idea对比一下,发现目录里面有的对应编译器都会有。
这就是一个很标准的gradle工程目录结构:
gradlew和gradlew.bat分别是Linux和Windows下的可执行脚本,具体业务逻辑是在/gradle/wrapper/gradle-wrapper.jar中实现,gradlew最终还是使用Java执行这个jar包来执行相关的Gradle操作的。
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
这段代码就是这个文件里面的内容,现在将逐一进行解读
而 distributionBase对应的值为:GRADLE_USER_HOME
我们继续看 Java、Android工程目录
如图所示
这里我们看到:这个俩个工程目录比刚刚多了个setting.gradle文件,现在来单独说明下这个文件具体有啥作用:
刚刚也说明了,settings文件在初始化阶段执行,那么其他阶段有哪些呢?这就要从Gradle生命周期开始说起了。
Gradle生命周期无非就是这三个:Initialization、Configuration、Execution
而这三个生命周期又与执行流程息息相关。
如图所示
从这张图可知,不同的阶段都有对应方法的调用顺序,在这里我们暂可熟悉这些即可:
刚刚已经讲解了setting.gradle的作用,现在接着讲解配置阶段相关的内容。
因为这里配置阶段和Gradle对应的Task(任务列表)相互绑定,所以这里不好拿代码单独解释配置相关的方法,需要结合Gradle任务一起讲,所以这里先忍耐一下,等讲完Task(任务列表)后,再一起解析。
Gradle Task:
注:task是gardle中最小的任务单元,犹如我们现在所常用的金钱单位0.01元一样(别钻牛角尖)。
概念都说了一大堆,接下来就到了愉快的撸码验证环节了。
创建java环境下的Gradle工程项目,进入build.gradle
this.beforeEvaluate {
println "this.beforeEvaluate"
}
//等同beforeEvaluate
this.gradle.beforeProject {
println "this.beforeProject"
}
this.afterEvaluate {
println "this.afterEvaluate"
}
//等同配置阶段完成后
this.gradle.afterProject {
println "this.afterProject"
}
this.gradle.taskGraph.whenReady{
println "whenReady"
}
// Gradle3.0 << ,在4.x以上就废弃了
task A {
println "configuration A.."
doFirst {
println "doFirst A.."
}
doLast {
println actions
println "doLast A1.."
}
}
task B{
println "configuration B.."
doFirst {
println "doFirst B.."
}
doLast {
println actions
println "doLast B1.."
}
}
this.gradle.buildFinished {
println "buildFinish"
}
代码解析
这里面开头那几个this指向对应的方法,就是刚刚我们执行流程图对应的方法,过后又定义了两个task任务单元,里面分别对不同的action有不同的打印输出,接下来我们看看运行效果:
运行效果一:运行taskA
如图所示
点击右边任务列表中的task或者点击左侧对应task的运行按钮
> Configure project :
configuration A..
configuration B..
this.afterProject
this.afterEvaluate
whenReady
> Task :A
doFirst A..
[org.gradle.api.internal.AbstractTask$ClosureTaskAction@261ae6e0, org.gradle.api.internal.AbstractTask$ClosureTaskAction@76e733fb]
doLast A1..
buildFinish
我们发现在配置阶段,两个Task里面的 configuration 都被打印了出来,随后就打印了配置结束的方法,以及准备进入到执行阶段的whenReady方法。因为运行的A任务,所以随后就进入了taskA的执行阶段,在执行阶段里,优先运行的doFirst 其次是doLast 对应的action,最后如愿的调用了buildFinish方法来结束整个Gradle编译。
不过这里有个小瑕疵:运行发现,配置前的beforeEvaluate、beforeProject对应方法并没有打印出来,如有知情的大佬知道其原因欢迎相互交流。不过这并不影响我们的发挥,因为每个任务的配置代码在构建的时候都会执行。
我们发现,单独运行A或者B的时候,配置阶段都执行了对应任务里面的配置,唯独运行没有一起运行,而我们在使用Android Gradle的时候,都是扒拉扒拉全运行完,就像配置阶段一样。那我们要怎样做呢?
task A {
println "configuration A.."
doLast {
println actions
println "doLast A1.."
}
}
task B{
println "configuration B.."
doLast {
println actions
println "doLast B1.."
}
}
A.dependsOn B
在这里我这只加了 A.dependsOn B 这段代码,看着意思就有点像,A继承B,运行一下A试试:
> Configure project :
configuration A..
configuration B..
> Task :B
[org.gradle.api.internal.AbstractTask$ClosureTaskAction@213f5745]
doLast B1..
> Task :A
[org.gradle.api.internal.AbstractTask$ClosureTaskAction@70cabab9]
doLast A1..
我们发现,运行A的时候,两者都一起运行了,但是问题来了,当我运行B的时候,又变成了单独运行,而且如果出现多个task怎么办呢?总不能相互 dependsOn 吧?
接下来又对代码进行一系列改造:
task A {
println "configuration A.."
doLast {
println actions
println "doLast A1.."
}
}
task B{
println "configuration B.."
doLast {
println actions
println "doLast B1.."
}
}
task C {
println "configuration C.."
doLast {
println "doLast C.."
}
}
task hello2(dependsOn: [A, C, B]) {
doLast {
println "doLast hello2"
}
}
这里我们看出,这里定义了新的任务hello,随后将已存在的task通过数组的形式相互绑定,换句话说,就是定义了一个管理类,将所有零散的任务单元全部管理了其他,想运行所有任务单元,只需要运行这个管理类即可。所以运行一下hello2任务单元试试:
> Configure project :
configuration A..
configuration B..
configuration C..
> Task :A
[org.gradle.api.internal.AbstractTask$ClosureTaskAction@40880123]
doLast A1..
> Task :B
[org.gradle.api.internal.AbstractTask$ClosureTaskAction@111c4be4]
doLast B1..
> Task :C
doLast C..
> Task :hello2
doLast hello2
BUILD SUCCESSFUL in 0s
4 actionable tasks: 4 executed
18:33:17: Task execution finished 'hello2'.
在代码里,我特意将 B和C相互兑换位置,结果发现,运行单位元,就是按照字母排序的方式依次运行。
现在又有新的问题,我们在使用任何对象的时候,使用完了都会被回收掉,那么任务执行完了,是不是也会有对应的回收任务?那该使用什么关键字呢?
接下来继续改造代码:
task A {
println "configuration A.."
doLast {
println actions
println "doLast A1.."
}
}
task B{
println "configuration B.."
doLast {
println actions
println "doLast B1.."
}
}
task C {
println "configuration C.."
doLast {
println "doLast C.."
}
}
task hello2(dependsOn: [A, C, B]) {
doLast {
println "doLast hello2"
}
}
task finalized {
doLast {
println "clear all tasks"
}
}
hello2.finalizedBy finalized
这里我们看到,又新增了一个task,里面表示执行清理逻辑,随后使用了 finalizedBy 关键字将,任务总管理和清理任务相互关联,运行效果看看
> Configure project :
configuration A..
configuration B..
configuration C..
> Task :A
[org.gradle.api.internal.AbstractTask$ClosureTaskAction@25b5129e]
doLast A1..
> Task :B
[org.gradle.api.internal.AbstractTask$ClosureTaskAction@74447d23]
doLast B1..
> Task :C
doLast C..
> Task :hello2
doLast hello2
> Task :finalized
clear all tasks
到这里,我们应该大概对Gradle任务有所了解了,每一个任务task都是最小单位,而每个task里都有对应的actions。而Gradle构建就是每一个任务单位相互执行后的结果。
本篇讲解到这里就结束了,相信你对Gradle基础以及构建机制有所认知,在下一篇里,将会继续对Gradle进行深一步的讲解。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/154154.html原文链接:https://javaforall.cn