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容器来创⽴:
doLast {
println "hello"
}
}
from(file('srcDir'))
into(buildDir)
}
下⾯的例⼦中,咱们应⽤ate办法,将新创建的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的⼀个实例对象。咱们还能够应⽤ Tasks() 来获取这个实例对象。
咱们看下TaskContainer的定义:
public interface TaskContainer extends TaskCollection, PolymorphicDomainObjectContainer
从定义上,咱们能够看出TaskContainer是⼀个task的汇合和域对象的汇合。
taskContainer中有四类⼗分重要的办法:
第⼀类是定位task的办法,有个别离是findByPath和getByPath。两个办法的区别就是findByPath如果没找到会返回null,⽽getByPath 没找到的话会抛出UnknownTaskException。
看下怎么应⽤:
task hello
ByPath('hello').path
ByPath(':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
CustomTask(String message, int number) {
this.number = number
}
}
下⾯咱们为CustomTask创⽴了⼀个带参数的构造函数,留神,这⾥须要带上@javax.inject.Inject注解,⽰意咱们前⾯能够传递参数给这个构造函数。
咱们能够这样应⽤:
也能够这样应⽤:
task myTask(type: CustomTask, constructorArgs: ['hello', 42])
第三类是register,register也是⽤来创⽴新的task的,不过register执⾏的是提早创⽴。也就是说只有当task被须要应⽤的时候才会被创⽴。
咱们先看⼀个register办法的定义:
TaskProvider register(String name,
Action super Task> configurationAction)
throws InvalidUrDataException
能够看到register返回了⼀个TaskProvider,有点像java多线程中的callable,当咱们调⽤()获取task值的时候,才会去创⽴这个task。
或者咱们调⽤ByName(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 !'
}
}
task intro {
dependsOn hello
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 {