gradle学习(14)-任务

1.任务的定义


之前我们定义任务的时候采用的是task + 任务名的方式。例如


task hello << {
        println "hello"
}

现在再介绍另外两种方式,和上面的定义是等价的。


task(hello)<<{
        println "hello"
}


task('hello')<<{
        println "hello"
}

gradle还提供了一个tasks容器来创建任务,通过调用create方法:


tasks.create(name:'hello')<<{
        println "hello"
}

2. 任务的定位


将任务看成项目的属性的方式


task hello
println hello.name
println project.hello.name

qianhuis-Mac-mini:0111_1 qianhui$ gradle -q hello
hello
hello


使用tasks容器来定位


task hello

println tasks.hello.name
println tasks['hello'].name

qianhuis-Mac-mini:0111_1 qianhui$ gradle -q hello
hello
hello

tasks.getByPath()方式来获得


task hello
println tasks.getByPath('hello').path
println tasks.getByPath(':hello').path

qianhuis-Mac-mini:0111_1 qianhui$ gradle -q hello
:hello
:hello

3.配置任务


task myCopy(type:Copy)
println myCopy.name

定义一个Copy类型名为myCopy的任务。


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q myCopy
myCopy

配置任务的第一种方式


Copy myCopy = task(myCopy,type:Copy)
myCopy.from 'resources'
myCopy.into 'target'
myCopy.include('**/*.txt','**/*.xml','**/*.properties')

这种方式每次都需要先显式的定义一个对象。比较麻烦。下面有另外一种更好的方式:


配置任务的第二种方式


Copy myCopy = task(myCopy,type:Copy)
myCopy{
        from 'resources'
        into 'target'
        include('**/*.txt','**/*.xml','**/*.properties')
}

这种方式适用于任何任务,第二行myCopy是tasks.getByName的缩写方式。这种方式在配置的时候是有作用的,在执行的时候是不起作用的。


配置任务的第三种方式


闭包方式:


task copy(type:Copy){
        from 'resources'
        into 'target'
        include('**/*.txt','**/*.xml','**/*.properties')
}


4.配置任务依赖


以任务名的方式定义依赖


依赖其他项目的任务,要想实现该例子,首先要记得settings.gradle在多项目的必要性,所以我们先编写settings.gradle:


include "projectA","projectB"

这样我们的build.gradle就能识别出这两个子项目,接下来在build.gradle中实现依赖其他项目的任务。


project('projectA'){
        task taskX(dependsOn:':projectB:taskY')<<{
                println 'taskX'
        }
}
project('projectB'){
        task taskY <<{
                println 'taskY'
        }
}

执行命令:


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q taskX
taskY
taskX

这是在根项目的build.gradle来定义2个子项目的任务。在正常情况下,我们应该是在各自的项目中,然后来定义项目之间的依赖,所以我们现在分拆taskX 和taskY两个任务到各自的目录中。


在projectA的build.gradle文件中添加:


task taskX(dependsOn:':projectB:taskY')<<{
        println 'taskX'
}


在projectB 的build.gradle文件中添加:


task taskY <<{
        println 'taskY'
}

然后将刚才跟目录中的build.gradle中的内容删除,避免造成任务冲突。然后在projectA 下执行命令:


qianhuis-Mac-mini:projectA qianhui$ gradle -q taskX
taskY
taskX

你可以通过task对象来配置依赖


task taskX << {
        println 'taskX'
}

task taskY <<{
        println 'taskY'
}

taskX.dependsOn taskY



输出:


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q taskX
taskY
taskX

使用闭包的方式配置依赖


当任务检查阶段,闭包会被传递到任务中,闭包可以返回单个任务或者一个任务集合,这些都会被当成他调用者的依赖项目。下面的例子就是将以lib开头的任务都当成taskX的依赖项目:


task taskX << {
        println 'taskX'
}

taskX.dependsOn{
        tasks.findAll{
                task -> task.name.startsWith('lib')
        }
}


task lib1<<{
        println 'lib1'
}

task lib2 <<{
        println 'lib2'
}

执行任务输出:


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q taskX
lib1
lib2
taskX


5.任务顺序


(该功能处在孵化阶段,以后可能会改变,所以需要注意)

任务顺序的两个规则:must run after 和 should run after。

当你定义taskX和taskY的关系是必须后执行,那就说明taskX必须在taskY任务执行完才能执行,无论在什么时候。

当你定义taskX和taskY的关系时应该后执行,那就说明不是强制要求的,只是这么做更好点,但是我们应该意识到我们讲should 等价于must还是比较好的。


现在来试试这两种顺序的执行的不同:


mustRunAfter


在build.gradle定义如下:


task taskX << {
        println 'taskX'
}
task taskY <<{
        println 'taskY'
}

taskX.mustRunAfter taskY

上面定义了taskX必须在taskY后执行,但是如果这个时候我们只执行taskX呢?


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q taskX
taskX

只执行taskY:


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q tasky
taskY


从上面可以看出,单独执行一个任务,是没有什么一样的。那现在我们同时执行两个任务:


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q tasky taskx
taskY
taskX
qianhuis-Mac-mini:0111_1 qianhui$ gradle -q taskx tasky
taskY
taskX

注意上面我们执行了两次,但是taskX和taskY顺序不一样,但是结果却是一样的,这就说明mustRunAfter奏效了。


shouldRunAfter


修改build.gradle文件:


task taskX << {
        println 'taskX'
}
task taskY <<{
        println 'taskY'
}

taskX.shouldRunAfter taskY

我们同样执行4次,输出如下:


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q tasky
taskY
qianhuis-Mac-mini:0111_1 qianhui$ gradle -q taskx
taskX
qianhuis-Mac-mini:0111_1 qianhui$ gradle -q taskx tasky
taskY
taskX
qianhuis-Mac-mini:0111_1 qianhui$ gradle -q tasky taskx
taskY
taskX


看出不同了么?我是没看出来,所以官方文档上的例子还是无法说明他们的区别,等有时间再去质问他们吧。

上面需要注意点的是:

taskX.shouldRunAfter taskY == taskX.shouldRunAfter(taskY)

taskX.mustRunAfter taskY ==  taskX.mustRunAfter(taskY)

其中的括号和空格时等效的。所以我们要了解的是gradle中调用方法的方式多种的。


有2种情况会使上面定义的顺序失效:2个任务之间有依赖和使用 --continue参数


来看看使之失效的例子,上面的例子taskX在taskY后执行,那么这个时候我们定义taskY依赖taskX呢。按我们之前学习依赖中得到的知识,依赖的任务要先执行到。那么看实际执行情况:


task taskX << {
        println 'taskX'
}
task taskY <<{
        println 'taskY'
}
taskY.dependsOn taskX
taskX.shouldRunAfter taskY


qianhuis-Mac-mini:0111_1 qianhui$ gradle -q tasky taskx
taskX
taskY

说明依赖的优先级要高于顺序的定义。


6.添加任务描述


build.gradle定义如下:


task taskX {
        description 'this a beatiful world'
        println 'taskX'
}
task taskY <<{
        description 'this a bad world'
        println 'taskY'
}

执行gradle tasks命令输出:



Other tasks
-----------
taskX - this a beatiful world
taskY


为什么taskX和taskY的有一个没有输出描述信息,在于taskY的定义中有<<,所以没能输出描述信息。那就说明任务的定义中这两种方式还是有一点区别的。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值