【Gradle系列】Gradle之Task

1,401 阅读3分钟

引言

上一阶段,我们知道了project是gradle的入口,同时细致了解了project系列知识, 如:Project的API家族概述/Project API/拓展属性等,更多具体的细节可以回顾下面章节:

Gradle 之Project详解(一)

Gradle之Project详解(二)

Gradle之Project详解(三)

接下来,我们将开启gradle的下一个重要的模块task;

定义

(1)直接task函数创建法,直接在 project 中定义task方式,最后都会被加到 project中的 tasks中,tasks 是一个TaskContainer类,主要是用来管理project中的所有的task;

代码:

task daviTask1 {
    println '============start 定义================'
    println '【task的定义】【直接task函数创建法】i am daviTask1'
    println '============end 定义================'

}

执行结果:

task-定义.png

(2)利用project的TaskContainer方式创建

this.tasks.create(name: 'daviTask2') {
    println '============start 定义======================='
    println '【task的定义】【TaskContainer】i am daviTask2'
    println '============end 定义========================='
}

配置

(1)定义的时候配置

代码:

task daviTask3(group: 'davi', description: 'davi 配置描述') {
    println '============start 定义=========================================='
    println '【task的配置】【定义的时候直接配置(key-valus模式)】i am daviTask3'
    println '============end 定义============================================='

}

执行结果:

配置组.png

(2)set方法配置

代码:

this.tasks.create(name: 'daviTask4') {
    println '============start 定义======================='

    setGroup('davi2')
    setDescription('davi2 配置描述')

    println '【task的配置】【set方法配置】i am daviTask4'
    println '============end 定义========================='
}

执行结果:

set方法配置.png

除了例子中的group,description属性之外我们可以配置,还有如下也可以配置(具体看自己的实际情况):

1.png

执行

代码:

task daviTask5(group: 'davi', description: 'davi 配置描述') {
    doFirst {
        println '============start task在执行阶段=========================================='
        println '【daviTask5】【task在执行阶段】【闭包中的...】i am daviTask5'
        println '============end task在执行阶段============================================='
    }
}
daviTask5.doFirst {
    println '============start task在执行阶段=========================================='
    println '【daviTask5】【task在执行阶段】【闭包外面的...】i am daviTask5, 先于闭包内的执行'
    println '============end task在执行阶段============================================='
}

执行结果:

执行阶段-里-外优先级.png

可以看出,外部指定的 doFirst 会比内部指定的先执行

小案例学习

通过task,统计【执行阶段】打包时长


//时机选择配置之后,确保task的拓扑图已经完成了
this.afterEvaluate { Project project ->
    println '============start 统计【执行阶段】打包时长=========================================='

    def startTime, endTime

    //执行阶段的第一个task都是'preBuild'
    def firstTask = project.tasks.getByName('preBuild')
    firstTask.doFirst {
        //记录第一个task执行之前的时间
        startTime = System.currentTimeMillis()
    }

    //执行阶段最后一个task是'build'
    def lastTask = project.tasks.getByName('build')
    lastTask.doLast {
        //记录最后一个task的执行之后的时间
        endTime = System.currentTimeMillis()
        //结果
        println "统计【执行阶段】打包时长结果为:${endTime - startTime}"

        println '============start 统计【执行阶段】打包时长=========================================='
    }

}

dependsOn依赖方式执行

代码:

task daviTask111(group: 'davi') {
    doLast {
        println "daviTask111 doLast 执行完了"
    }
}

task daviTask222(group: 'davi') {
    doLast {
        println "daviTask222 doLast 执行完了"
    }
}

//dependsOn 依赖
task daviTask333(group: 'davi', dependsOn: [daviTask111, daviTask222]) {
    doLast {
        println "daviTask333 doLast 执行完了"
    }
}

执行结果:

执行顺序-依赖-dependsOn.png

task的输入和输出

实现利用task的输入输出,实现把字符串写入文件;

def taskApiFile
task taskWriteApiFile(group: 'davi') { Task t ->
    //定义
    def vName = '1.0.0111'
    taskApiFile = file('taskApiFile.xml')
    if (!taskApiFile.exists()) {
        println "【输入输出方式】 【taskWriteApiFile】文件不存在,创建.."
        taskApiFile.createNewFile()
    } else {
        println "【输入输出方式】 【taskWriteApiFile】文件存在.."
    }

    //指定输入
    t.getInputs().property('vName', vName)
    //指定输出
    t.getOutputs().file(taskApiFile)

    //输出输出的执行使用
    t.doLast {
        println "【输入输出方式】 【taskWriteApiFile】输入的内容,保存到输出的文件中.."

        //获取输入/输出
        Map<String, Object> data = t.getInputs().getProperties()
        File f = t.getOutputs().getFiles().singleFile

        //输入的内容,保存到输出的文件中
        StringWriter sw = new StringWriter()
        sw.write(data.get('vName'))
        f.withWriter { BufferedWriter writer ->
            writer.append(sw.toString())
        }
    }
}

mustRunAfter 方式执行

代码:

task task666(group: 'davi') { Task t ->
    t.doLast {
        println "task666"
    }
}

task task777(group: 'davi') { Task t ->
    t.mustRunAfter(task666)

    t.doLast {
        println "task777"
    }
}

task task888(group: 'davi') { Task t ->
    t.mustRunAfter(task777)

    t.doLast {
        println "task888"
    }
}

task taskTest667788(group: 'davi') { Task t ->
    t.dependsOn(task777, task888, task666)
}

执行结果:

mustRunAfter.png

自定义的task,挂到Gradle的build过程中

代码:

task taskBeforePreBuild(group: 'davi') { Task t ->
    println "配置阶段:【taskAfterPreBuild】"
    doLast {
        println "执行阶段:【taskAfterPreBuild】"
    }
}


this.project.afterEvaluate { Project p ->
    println "配置阶段完成后.."

    def preBuild = p.tasks.getByName('preBuild')
    preBuild.dependsOn(taskBeforePreBuild)
}

执行结果:

taskBeforePreBuild.png

结尾

哈哈,该篇就写到这里(一起体系化学习,一起成长)

Tips

更多精彩内容,请关注 “Android热修技术” 微信公众号