深入理解gradle项目构建---Task学习

阅读本篇内容请先了解Gradle Project的相关概念
深入理解Gradle项目构建,你需要知道这些
关于gradle project的其实你可以理解为build.gradle。一个build.gradle就代表一个project。

一、task定义

下面讲述一下关于Task的概念:
task其实里可以理解成gradle project的构建单元,Android代码编译其实就是执行一个个task任务。通过./gradlew tasks命令当前的project下有多少个task。下面来看一下task如何定义:
第一种方式,直接通过task函数定义

task mytask{
    println "我是一个task任务"
}

可以通过源码直接了解如何创建

/**
* <p>Creates a {@link Task} with the given name and adds it to this project. Calling this method is equivalent to
* calling {@link #task(java.util.Map, String)} with an empty options map.</p>
* @param name The name of the task to be created
* @return The newly created task object
*/
Task task(String name) throws InvalidUserDataException;

执行验证一下

dsh$ ./gradlew mytask

我是一个task任务

第二种方式,使用tasks容器创建

this.tasks.create(name:"mytask2"){
    println "我是mytask2任务"
}

执行一下

dsh$ ./gradlew mytask2

我是一个task任务
我是mytask2任务

从执行结果上看第二种创建方式也是可行的,但是细心的同学可能很好奇,为什么执行./gradlew mytask2打印输出了mytask里的输出了呢?原因是执行task的时候,会经历一段配置阶段,我们的打印语句都在配置阶段被执行了。怎样让我们的打印语句执行在task的执行阶段呢?下面介绍的两个方法就可以做到doFirstdoLast

this.tasks.create(name:"mytask2"){
    println "我是mytask2任务"
    doFirst {
        //该任务执行前被执行
        println "我是mytask2任务 doFirst"
    }

    doLast {
        //该任务执行后执行
        println "我是mytask2任务 doLast"
    }
}

执行一下

localhost:GradleStudy dsh$ ./gradlew mytask2
初始化阶段开始啦。。。。
> Configure project :app
我是一个task任务
我是mytask2任务

> Task :app:mytask2
我是mytask2任务 doFirst
我是mytask2任务 doLast

可以看到我们的doFirst和doLast执行的时间是在gradle的执行阶段执行的。
下面写一个案例来加深对task的理解
计算编译期间所有task执行的时间

this.afterEvaluate { project ->
    def preBuildTask = project.tasks.getByName("preBuild")
    def startTime
    def endTime
    preBuildTask.doFirst {
        startTime = System.currentTimeMillis()

    }



    def buildTask = project.tasks.getByName("build")
    buildTask.doLast {
        endTime = System.currentTimeMillis()
    }

     println "编译期间所有task执行用时 ${startTime - endTime}"

}

执行一下

 ./gradlew build

> Task :app:preBuild
编译期间开始时间 1525958501917

> Task :app:lint
> Task :app:build
编译期间所有task执行用时 11047

二、task的执行顺序

1、dependsOn强依赖的方式

定义3个task

task task1{
    setGroup("study")
    doLast{
        println "执行了task1"
    }
}

task task2{
    setGroup("study")
    doLast{
        println "执行了task2"
    }
}

task task3(dependsOn:[task2,task1]){
    setGroup("study")
    doLast{
        println "执行了task3"
    }
}

执行一下

./gradlew task3

> Task :task1
执行了task1

> Task :task2
执行了task2

> Task :task3
执行了task3

通过上面的打印可以知道,task3 的执行依赖于task1 和2,所以通过dependsOn改变task的执行顺序。
下面写一个小程序练习一下

//将当前project目录下的releases的每个子节点的内容解析到generated/release/以文件的形式保存
task handleRelease {
    def soureceFile = file("releases.xml")
    def destDir = new File(this.buildDir,"generated/release/")

    doLast {
        if (!destDir.exists()) {
            destDir.mkdir()
        }

        def releases = new XmlParser().parse(soureceFile)
        releases.release.each { releaseNode ->

            //解析节点内容
            def versionCode = releaseNode.versionCode.text()
            def versionName = releaseNode.versionName.text()
            def versionInfo = releaseNode.versionInfo.text()

            //创建文件并写入节点数据
            def destFile = new File(destDir,"release-${versionName}.txt")
            destFile.withWriter {writer->
                writer.write("${versionCode}+${versionName}+${versionInfo}")
            }

        }
    }

}

//利用dependsOn 执行我们解析xml的task任务
task testHandleRelease(dependsOn:[handleRelease]){
    doLast{

        def dir = fileTree(this.buildDir.path+"generated/release/")
        dir.each {
            println "this file is ${it}"
        }
    }

}

2、通过输入输出的方式指定

TaskInputsTaskOutputs

————–2018-05-10———————–

猜你喜欢

转载自blog.csdn.net/dingshuhong_/article/details/80273273