六: Gradle中的task

配置脚本的最终目的,是运行对应的task。在脚本中定义task可理解为定义一个java类,Gradle运行时会根据需要创建task instance。有两个重要的类可供参考:

  • TaskContainer 。project instances中的tasks属性,保存运行时生成的task instance。
  • Task。Task接口定义

Type

这样定义一个新的tasks时:

tasks.register('hello') {
    doLast {
        println 'hello'
    }
}

相当于注册了一个匿名的task类,该task运行时生成的实例是’hello‘。这个task不存在复用的可能性。

但我们可以自定义有名称的Task:

abstract class GreetingTask extends DefaultTask {
    @TaskAction
    def greet() {
        println 'hello from GreetingTask'
    }
}

创建了一个有名称可复用的GreetingTask。这种可复用的task叫做Task type。

基于给定Type创建一个新的Task ‘hello’,这个task继承了GreetingTask的属性和方法

// Create a task using the task type
tasks.register('hello', GreetingTask)

Gradle内置了许多Task types,可使用系统自带的Task type

//copy task继承自Copy,可以使用Copy中的from ,into等方法
def copy = tasks.register('copy', Copy) {
    from(file('srcDir'))
    into(buildDir)
}

Configure task

task可以有好几种配置方式:

//定义时配置
tasks.register('task2'){
    println "configured by register"
}

//通过named名字配置
def reftask2 = tasks.named('task2'){
    println "configured by tasks.named"
}

//通过引用配置
reftask2.configure{
    println "configured by reference"
}
//直接通过名字配置
task2{
   println "configured by task name"
}

观察一下输出,几个配置都生效了:

$ gradle task2
Configuration on demand is an incubating feature.
configured by register
configured by tasks.named
configured by reference
configured by task name

BUILD SUCCESSFUL in 1s

Dependency and DAG

Task之间可以指定依赖。比如task X依赖于task Y, 则运行task X时,会先执行task Y

def taskX = tasks.register('taskX') {
    doLast {
        println 'taskX'
    }
}

def taskY = tasks.register('taskY') {
    doLast {
        println 'taskY'
    }
}

taskX.configure {
    dependsOn taskY
}

检查某个task的依赖:

gradle taskName -m

一个task可以有多个依赖,因为依赖的存在,所有的task就形成了一颗DAG树,这是从Gradle官网扒过来的例子:

Example task graphs

DAG, Directed Acyclic Graphs,有向无环图。这种图的特征是:

  • 从根节点往前遍历,每一条路都可以直达尾节点,不会成环
  • 从尾节点往回追溯,可以回到根节点,不会成环
  • 从根节点到尾节点之间的各路径之间,存在重复或交叉

Task rules

Task其他属性都很好理解,有兴趣的可以自己去扒官网,其中烧脑一点的是Task rules。

正常情况下,gradle的使用都是

gradle taskname

正常运行的前提是要求task必须存在。

如果用户输入一个不存在的task,你想动态创建并运行该task的时候,就使用task rules

比如说你管理100台机器,需要创建100个task,这些task的名字分别是pingServer1..pingServer100,你不想手动写这么多task,你可以利用task rules动态创建:

//如果task不存在就进入task rules
tasks.addRule("Pattern: ping<ID>") { String taskName ->
    if (taskName.startsWith("ping")) {
          //动态创建task
          task(taskName) {
              println "Pinging: " + (taskName - 'ping')
          }
    }
}

然后你就可以调用这些一开始并不存在的task了,这些task被调用后会进入task rules,然后被动态创建,然后被执行:

$ gradle pingServer1
Configuration on demand is an incubating feature.
Pinging: Server1

$ gradle pingServer100
Configuration on demand is an incubating feature.
Pinging: Server100

BUILD SUCCESSFUL in 929ms

通过task rules动态创建的task可以被其他task正常使用,比如说这样,新建一个groupPing task,依赖于task rules创建的pingServer1和pingServer2

tasks.register('groupPing') {
    dependsOn 'pingServer1', 'pingServer2'
}

lifecycle task

lifecycle我们都知道,是编译步骤的一个分组,比如maven就有clean, default和site三个lifecycle

Gradle里面的lifecycle这个概念非常的弱。并不像maven一样,强调lifecycle和phase,可以自定义lifecycle。

Gradle由于Task DAG的存在,可以方便的创建工作流,只需要指定 依赖关系就可以。因此Grade引入了一种特殊的task,叫做lifecyle task。事实上,lifecycle task基本上是一个空的task。当你把这个空的task依赖到一堆有实际意义的task上时,运行这个空task就可以调用它依赖的所有task。

比如说我们常用的命令,gradle build。这个build就是一个lifecycle task。它本身什么都不做,但是他会依赖于一大堆task:

$ gradle build -m
Configuration on demand is an incubating feature.
:app:compileJava SKIPPED
:app:processResources SKIPPED
:app:classes SKIPPED
:app:jar SKIPPED
:app:startScripts SKIPPED
:app:distTar SKIPPED
:app:distZip SKIPPED
:app:assemble SKIPPED
:app:compileTestJava SKIPPED
:app:processTestResources SKIPPED
:app:testClasses SKIPPED
:app:test SKIPPED
:app:check SKIPPED
:app:build SKIPPED

因此当我们调用build的时候,是执行了它前面的那些task,从compoileJava一直执行到check。

Gradle的Base Plugin定义了一些标准的lifecycle tasks:standard lifecycle tasks, 比如build , assembe ,check等。但具体的工作是用户引入的Plugin提供的,Plugin给这些lifecycly task添加依赖,引入task,最终可以执行完整的工作流。

比如上面的build task,是在Base Plugin中定义的,但什么都不会做。当我们使用java application plugin的时候,才会由java application plugin引入了具体的tasks间依赖关系。才会有grade build正常执行



《 “六: Gradle中的task” 》 有 2 条评论

  1. Fish oil, insulin sensitivity, insulin secretion and glucose tolerance in healthy people is there any effect of fish oil supplementation in relation to the type of background diet and habitual dietary intake of n 6 and n 3 fatty acids cytotec prices

  2. stomach Cancer chemotherapeutic agents Cyclophosphamide, chlorambucil, thiotepa, busulfan Leukemias Asbestos Lung cancer, mesothelioma Heavy metals Nickel, chromium, cadmium Lung Arsenic Skin Vinyl chloride Liver angiosarcoma priligy united states

回复 can you buy generic cytotec 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About Me

一位程序员,会弹吉他,喜欢读诗。
有一颗感恩的心,一位美丽的妻子,两个可爱的女儿
mail: geraldlee0825@gmail.com
github: https://github.com/lisuxiaoqi
medium: https://medium.com/@geraldlee0825