java中什么是task_关于java:深入理解gradle中的task

简介

在之前的文章中,咱们讲到了如何应用gradle创立一个简略的task,以及task之间怎么依赖,甚至应用了程序来创立task。在本文中,咱们会更加深刻的去理解一下gradle中的task。

定义task

定义一个task能够有很多种形式,比方上面的应用string作为task的名字:

task('hello') {

doLast {

println "hello"

}

}

task('copy', type: Copy) {

from(file('srcDir'))

into(buildDir)

}

还能够应用tasks容器来创立:

tasks.create('hello') {

doLast {

println "hello"

}

}

tasks.create('copy', Copy) {

from(file('srcDir'))

into(buildDir)

}

下面的例子中,咱们应用tasks.create办法,将新创建的task加到tasks汇合中。

咱们还能够应用groovy特有的语法来定义一个task:

task(hello) {

doLast {

println "hello"

}

}

task(copy, type: Copy) {

from(file('srcDir'))

into(buildDir)

}

tasks 汇合类

下面咱们在创立task的时候,应用了tasks汇合类来创立task。

实际上,tasks汇合类是一个十分有用的工具类,咱们能够应用它来做很多事件。

间接在build文件中应用tasks,实际上是援用了TaskContainer的一个实例对象。咱们还能够应用 Project.getTasks() 来获取这个实例对象。

咱们看下TaskContainer的定义:

public interface TaskContainer extends TaskCollection, PolymorphicDomainObjectContainer

从定义上,咱们能够看出TaskContainer是一个task的汇合和域对象的汇合。

taskContainer中有四类十分重要的办法:

第一类是定位task的办法,有个别离是findByPath和getByPath。两个办法的区别就是findByPath如果没找到会返回null,而getByPath没找到的话会抛出UnknownTaskException。

看下怎么应用:

task hello

println tasks.getByPath('hello').path

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

输入:

:hello

:hello

第二类是创立task的办法create,create办法有多种实现,你能够间接通过名字来创立一个task:

task('hello') {

doLast {

println "hello"

}

}

也能够创立特定类型的task:

task('copy', type: Copy) {

from(file('srcDir'))

into(buildDir)

}

还能够创立带参数的构造函数的task:

class CustomTask extends DefaultTask {

final String message

final int number

@Inject

CustomTask(String message, int number) {

this.message = message

this.number = number

}

}

下面咱们为CustomTask创立了一个带参数的构造函数,留神,这里须要带上@javax.inject.Inject注解,示意咱们前面能够传递参数给这个构造函数。

咱们能够这样应用:

tasks.create('myTask', CustomTask, 'hello', 42)

也能够这样应用:

task myTask(type: CustomTask, constructorArgs: ['hello', 42])

第三类是register,register也是用来创立新的task的,不过register执行的是提早创立。也就是说只有当task被须要应用的时候才会被创立。

咱们先看一个register办法的定义:

TaskProvider register​(String name,

Action super Task> configurationAction)

throws InvalidUserDataException

能够看到register返回了一个TaskProvider,有点像java多线程中的callable,当咱们调用Provider.get()获取task值的时候,才会去创立这个task。

或者咱们调用TaskCollection.getByName(java.lang.String)的时候也会创立对应的task。

最初一类是replace办法:

Task replace​(String name)

T replace​(String name,

Class type)

replace的作用就是创立一个新的task,并且替换掉同样名字的老的task。

Task 之间的依赖

task之间的依赖关系是通过task name来决定的。咱们能够在同一个我的项目中做task之间的依赖:

task hello {

doLast {

println 'Hello www.flydean.com!'

}

}

task intro {

dependsOn hello

doLast {

println "I'm flydean"

}

}

也能够跨我的项目进行task的依赖,如果是跨我的项目的task依赖的话,须要制订task的门路:

project('project-a') {

task taskX {

dependsOn ':project-b:taskY'

doLast {

println 'taskX'

}

}

}

project('project-b') {

task taskY {

doLast {

println 'taskY'

}

}

}

或者咱们能够在定义好task之后,再解决task之间的依赖关系:

task taskX {

doLast {

println 'taskX'

}

}

task taskY {

doLast {

println 'taskY'

}

}

还能够动静增加依赖关系:

task taskX {

doLast {

println 'taskX'

}

}

// Using a Groovy Closure

taskX.dependsOn {

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

}

task lib1 {

doLast {

println 'lib1'

}

}

task lib2 {

doLast {

println 'lib2'

}

}

task notALib {

doLast {

println 'notALib'

}

}

定义task之间的程序

有时候咱们的task之间是有执行程序的,咱们称之为对task的排序ordering。

先看一下ordering和dependency有什么区别。dependency示意的是一种强依赖关系,如果taskA依赖于taskB,那么执行taskA的时候肯定要先执行taskB。

而ordering则是一种并不太强列的程序关系。示意taskA须要在taskB之后执行,然而taskB不执行也能够。

在gradle中有两种order:别离是must run after和should run after。

taskA.mustRunAfter(taskB)示意必须恪守的程序关系,而taskA.shouldRunAfter(taskB)则不是必须的,在上面两种状况下能够疏忽这样的程序关系:

第一种状况是如果shouldRunAfter引入了order循环的时候。

第二种状况是如果在并行执行的状况下,task所有的依赖关系都曾经满足了,那么也会疏忽这个程序。

咱们看下怎么应用:

task taskX {

doLast {

println 'flydean.com'

}

}

task taskY {

doLast {

println 'hello'

}

}

taskY.mustRunAfter taskX

//taskY.shouldRunAfter taskX

给task一些形容

咱们能够给task一些形容信息,这样咱们在执行gradle tasks的时候,就能够查看到:

task copy(type: Copy) {

description 'Copies the resource directory to the target directory.'

from 'resources'

into 'target'

include('**/*.txt', '**/*.xml', '**/*.properties')

}

task的条件执行

有时候咱们须要依据build文件中的某些属性来判断是否执行特定的task,咱们能够应用onlyIf :

task hello {

doLast {

println 'www.flydean.com'

}

}

hello.onlyIf { !project.hasProperty('skipHello') }

或者咱们能够抛出StopExecutionException异样,如果遇到这个异样,那么task前面的工作将不会被执行:

task compile {

doLast {

println 'We are doing the compile.'

}

}

compile.doFirst {

if (true) { throw new StopExecutionException() }

}

task myTask {

dependsOn('compile')

doLast {

println 'I am not affected'

}

}

咱们还能够启动和禁用task:

myTask.enabled = false

最初咱们还能够让task超时,当超时的时候,执行task的线程将会被中断,并且task将会被标记为failed。

如果咱们想继续执行,那么能够应用 –continue。

留神, 只有可能响应中断的task,timeout才有用。

task hangingTask() {

doLast {

Thread.sleep(100000)

}

timeout = Duration.ofMillis(500)

}

task rule

如果咱们想要给某些task定义一些规定,那么能够应用tasks.addRule:

tasks.addRule("Pattern: ping") { String taskName ->

if (taskName.startsWith("ping")) {

task(taskName) {

doLast {

println "Pinging: " + (taskName - 'ping')

}

}

}

}

上咱们定义了一个rule,如果taskName是以ping结尾的话,那么将会输入对应的内容。

看下运行后果:

> gradle -q pingServer1

Pinging: Server1

我还能够将这些rules作为依赖项引入:

task groupPing {

dependsOn pingServer1, pingServer2

}

Finalizer tasks

和java中的finally一样,task也能够指定对应的finalize task:

task taskX {

doLast {

println 'taskX'

}

}

task taskY {

doLast {

println 'taskY'

}

}

taskX.finalizedBy taskY

> gradle -q taskX

taskX

taskY

finalize task是肯定会被执行的,即便下面的taskX中抛出了异样。

总结

以上就是gradle中task的详解,心愿大家可能喜爱。

本文已收录于 http://www.flydean.com/gradle-task-in-depth/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」,懂技术,更懂你!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值