美文网首页
Gradle 之详解Task(四)

Gradle 之详解Task(四)

作者: PuHJ | 来源:发表于2019-04-08 10:57 被阅读0次

    一、前言

    Gradle在初始化阶段会生成所有的Project对象,在配置阶段会构建Task有向无环图,最后的执行阶段会执行该Task和其相关的Task任务。

    这一章主要说下,配置阶段之前的Task的构建和Task的执行(没有调用该Task也会让配置阶段执行代码执行)。

    二、Task的定义

    通过gradlew tasks可查看所有定义好的Task任务。

    Task定义方式:

    1、Task task(String name,Closure configureClosure)

    如:

    task helloTask {
        println 'hello world'
    }
    
    等价于:
    task (helloTask,{
        println 'hello world'
    }) 
    

    上面的调用:gradlew helloTask;强调一点的是该helloTask的执行在配置阶段中。

    2、TaskContainer getTasks() 通过容器

    如:

    this.getTasks().create(name:'helloTask') {
        println 'hello world'
    }
    

    每个Project中会有个TaskContainer对象,该对象是为了管理该Project下的所有的Task。

    无论通过第一个方式还是第二个方式都会有个XXXXX(Map<String, ?> options, Closure configureClosure),第一个参数options是什么意思?

    我们通过task(String name,Closure configureClosure)方式创建的时候,第一个String name实质也可以理解成map的方式,也就是说map可以保存很多的设置属性。而且这些设置属性都在Task的声明中。

    public interface Task extends Comparable<Task>, ExtensionAware {
        String TASK_NAME = "name";
    
        String TASK_DESCRIPTION = "description";
    
        String TASK_GROUP = "group";
    
        String TASK_TYPE = "type";
    
        String TASK_DEPENDS_ON = "dependsOn";
    
        String TASK_OVERWRITE = "overwrite";
    
        String TASK_ACTION = "action";
    }
    
    • name : Task名称
    • description : Task描述
    • group : Task属于哪个组
    • type : Task类型
    • dependsOn : Task依赖于其他的Task
    • overwrite :
    • action:

    Task中除了定义属性外,还有对该属性的操作方法,我们可以在创建Task的时候就对添加属性,也可以通过获取特定的属性通过setXXX方法设置。

    二、Task的执行

    前面也已经介绍了Task的执行方式是调用gradlew task名方式,上面的Task定义的是执行在配置阶段的,而且及时没有明确的被调用该Task中的代码还是会在配置阶段执行。

    Task可以通过配置的方式,让其执行在配置阶段还是执行阶段。

    1、doFirst{} : 执行阶段

    添加doFirst代码是执行阶段执行;不添加表示在配置阶段执行。

    如:可以在Task中添加doFirst,也可以通过找到Task添加doFirst。

    this.getTasks().create(name: 'helloTask',description: 'hahahha') {
        doFirst {
            def name = 'hello'
            println name
        }
    }
    
    helloTask.doFirst {
        println it.description
    }
    
    2、doLast{} : 执行阶段

    在Task中通过添加doLast,可以让这部分代码执行在执行阶段

    如:创建一个helloTask任务,通过执行该任务,他的打印结果为:“world”,因为配置阶段的先执行,最后再顺序执行执行阶段内容。

    this.getTasks().create(name: 'helloTask',description: 'hahahha') {
        def name = 'hello'
        doLast {
            println name
        }
        name = 'world'
    }
    
    
    3、<< : 执行阶段

    当Task中的代码都执行在执行阶段的时候,用<<来简写代替doLast

    this.getTasks().create(name: 'helloTask',description: 'hahahha') << {
        def name = 'hello'
        println name
    }
    

    例子:计算执行执行阶段到执行阶段结束时间

    this.afterEvaluate { Project project->
        def startBuildTime,endBuildTime
        def preBuildTask = project.tasks.getByName('preBuild')
        def buildTask = project.tasks.getByName('build')
    
        preBuildTask.doFirst {
            startBuildTime = System.currentTimeMillis()
            println "preBuildTask time is ${startBuildTime}"
        }
    
        buildTask.doLast {
            endBuildTime = System.currentTimeMillis()
            println "preBuildTask time is ${endBuildTime}"
            println "执行时间为: ${endBuildTime-startBuildTime}"
        }
    }
    

    二、Task的执行顺序

    Task的执行顺序:

    • 1、dependOn方式设置
    • 2、输入输出方式
    • 3、通过API指定顺序

    1)、dependOn方式

    如:

    task taskZ << {
        println 'taskZ'
    }
    
    task taskX(dependsOn: taskZ) << {
        println 'taskX'
    }
    
    task taskY(dependsOn: [taskX,taskZ]) << {
        println 'taskY'
    }
    

    定义了taskX、taskY和taskZ三个Task,并指定taskY依赖于taskX,而taskX依赖于taskZ;当执行taskY的时候他们的输出顺序如下:

    taskZ
    taskX
    taskY
    

    2)、输入输出方式

    当一个参数作为TaskA的输出参数,却作为TaskB的输入参数。那么当执行TaskB的时候先要执行TaskA。即输出的Task先于输入的Task执行。
    输入方式:

    • TaskInputs property(String name, Object value);
    • TaskInputs properties(Map<String, ?> properties);

    通过输入一些键值对的方式,KEY为String类型,value为任意类型。

    输出方式:

    • TaskOutputFilePropertyBuilder dirs(Object... paths);
    • TaskOutputFilePropertyBuilder file(Object path);
    • TaskOutputFilePropertyBuilder dir(Object path);

    3)、指定顺序方式mustRunAfter

    如:

    task taskX << {
        doLast {
            println 'taskX'
        }
    
    }
    
    task taskY  {
        mustRunAfter(taskX)
    
        doLast {
            println 'taskY'
        }
    }
    
    task taskZ << {
        mustRunAfter(taskY)
        doLast {
            println 'taskZ'
        }
    
    }
    

    三、Gradle生命周期内执行Task

    怎么样通过代码调用Task

    this.afterEvaluate {
        def buildTask = it.tasks.findByName('build')
        if (buildTask != null) {
            buildTask.doLast {
                taskZ.execute()
            }
        }
    }
    

    在buildTask执行中添加对taskZ的执行。

    相关文章

      网友评论

          本文标题:Gradle 之详解Task(四)

          本文链接:https://www.haomeiwen.com/subject/mfyjiqtx.html