美文网首页
第三十四节 gradle中的project和task

第三十四节 gradle中的project和task

作者: 最美下雨天 | 来源:发表于2018-06-01 15:54 被阅读14次

project和task是gradle领域中两个主要的对象,project为task提供了执行的容器和上下文
我们来看张图


image.png

点进去project看下,可以看到它是一个接口


image.png
解释下gradle的构建流程:gradle在构建的时候首先会根据build.gradle配置文件创建一个project实例,然后执行project实例,build.gradle中的所有代码都会通过task任务的方式插入到project中,project实例可以在配置文件中通过project隐式调用,什么意思呢?
project.version=""可以简写为version=""

什么是task呢,每一个操作都可以定义为一个task任务

plugins {
    application
    //配置kotlin插件,支持kotlin jvm
    kotlin("jvm")
}

这个application插件中就包含了很多的task

定义任务

我们可以这样定义一个任务:

//有两个参数,第一个是任务的名称,第二个是个lambda表达式,是任务的具体逻辑
task("这是任务的名称",{

    println("任务的逻辑")

})

定义完成后,在gradle面板中的other任务集中会多出来个任务


image.png

双击这个任务


image.png
这儿有个误区:为什么任务的逻辑会先于执行任务之前打印出来呢?其实这个涉及到任务的生命周期
task生命周期:  先扫描  再执行 

可以再写个任务,看下什么效果

//有两个参数,第一个是任务的名称,第二个是个lambda表达式,是任务的具体逻辑
task("这是任务的名称",{

    println("任务的逻辑")

})
task("这是任务的名称2",{

    println("任务的逻辑2")

})
image.png

双击任务2可以看到任务1也打印了,这就是任务的扫描


image.png

如果我们想让任务在真正执行时才执行闭包中的逻辑,可以运用下doFirst()和doLast()方法

//有两个参数,第一个是任务的名称,第二个是个lambda表达式,是任务的具体逻辑
task("这是任务的名称",{

    doFirst {
        println("任务的逻辑")
    }


})
task("这是任务的名称2",{

    doFirst {
        println("任务的逻辑2")
    }
})

现在再次双击任务2


image.png

任务的依赖

task("做饭",{
    doFirst {
        println("做饭")
    }

}).dependsOn("切菜")

task("买菜",{
    doFirst {
        println("买菜")
    }
})

task("切菜",{
    doFirst {
        println("切菜")
    }
}).dependsOn("买菜")
image.png

双击“做饭”,可以看到三个任务都执行了

image.png

还可以对每个任务添加group属性对任务进行分组

task("做饭",{
    group="自定义"
    doFirst {
        println("做饭")
    }

}).dependsOn("切菜")

task("买菜",{
    group="自定义"
    doFirst {
        println("买菜")
    }
})

task("切菜",{
    group="自定义"
    doFirst {
        println("切菜")
    }
}).dependsOn("买菜")
image.png

默认属性

task("查看所有默认属性",{
    properties.forEach { t, any ->
        println("key=${t},value=${any}")
    }
})

执行任务:


image.png

增量更新

自己的理解:如果一个任务第二次执行的结果跟第一次执行的结果是相同的,那么第二次执行这个任务时,其实是没有必要执行的
模拟一个场景:我们统计一下src目录下所有的文件并且将文件的名字写入一个新文件中info.txt

task("统计src下所有的文件",{
    doFirst {
        //定义源路径
        var files=fileTree("src")
        //定义接收文件的路径
        var infoTxt=File("info.txt")
        files.forEach {
            if(it.isFile)
            {
                //模拟任务耗时
                Thread.sleep(1000)
                infoTxt.appendText(it.name)
                infoTxt.appendText("\n")
            }
        }

    }
})

src下的所有文件:


image.png

执行任务:


image.png

看下生成的info.txt文件


image.png
image.png
我们重复执行”统计src下所有的文件“这个任务,发现这个任务总耗时并没有发生变化

gradle构建之所以优秀的原因就是增量更新,但是这儿并体现不出来,因为它不知道任务所涉及的文件有没有发生变化,我们需要指定输入源、输出源,只要这两个地方一个发生变化,任务就有执行的必要,否则没有
• inputs.dir()
• inputs.file()
• outputs.dir()
• outputs.file()
修改下任务逻辑

task("统计src下所有的文件",{
    //注意位置
    inputs.dir("src")
    outputs.file("info.txt")
    doFirst {
        //定义源路径
        var files=fileTree("src")
        //定义接收文件的路径
        var infoTxt=File("info.txt")
        files.forEach {
            if(it.isFile)
            {
                //模拟任务耗时
                Thread.sleep(1000)
                infoTxt.appendText(it.name)
                infoTxt.appendText("\n")
            }
        }

    }
})

如果不改变输入源和输出源多次运行:


image.png

发现任务耗时为0,其实就没有执行

相关文章

网友评论

      本文标题:第三十四节 gradle中的project和task

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