gradle task总结

今天我们来总结下Gradle 中task的相关知识点,gradle中的project和task真的是太太太重要了。在Gradle中可以有很多的Project,Project就是抽出来的一个个独立的模块,所有的Project组成了整个Gradle的构建。一个Project可以包含很多的Task,Task就是一个操作,比如上传jar到maven,复制一份文件,输出lint报告等等。打个不是很恰当的比喻,Project可以看做Java中的类,task就是这个类里面的一个个方法。

今天概念性的东西会比较多,主要从下面几个方面:

1 Task的创建
2 Task的常用属性
3 Task的执行分析

1.Task的创建

常用的task创建方式有4种,下面我们分别来看一下:

1.1第一种创建方式

第一种就是通过task的原型
Task task(String name) throws InvalidUserDataException;
用法如下,创建了一个名字是createTask1Name的task,返回类型是Task的createTask1,这样我们就可以在脚本中对这个task进行其他操作。

def Task createTask1 = task(createTask1Name)
createTask1.doLast{
    println '第一种创建方法'
}

怎么运行上面这个task就很简单了:

$ gradle createTask1
:createTask1Name
第一种创建方法

BUILD SUCCESSFUL

Total time: 0.834 secs
1.2第二种创建方式

第二种方法就是通过name和对该任务的配置Map来创建任务,原型就是:

Task task(Map<String, ?> args, String name) throws InvalidUserDataException;

用法如下:

def Task createTask2 = task(description: '任务创建方式2', createTask2)
createTask2.doLast{
    println '第二种创建方法'
}

运行效果:

$ gradle createTask2
:createTask2
第二种创建方法

BUILD SUCCESSFUL

Total time: 0.872 secs

我们看一下这个task的信息,可以看出description属性生效了,同理也可以配置task的其他属性。

$ gradle help --task createTask2
:help
Detailed task information for createTask2

Path
     :createTask2

Type
     Task (org.gradle.api.Task)

Description
     任务创建方式2

Group
     -

BUILD SUCCESSFUL

Total time: 0.811 secs

常用的配置属性有下面这些:

1 type:基于一个存在的task来创建,和继承差不多意思
2 description:配置任务的描述
3 group:用于配置任务的分组
4 dependsOn:配置任务的依赖
5 action:添加action

1.3第三种创建方式

第三种创建的原型:

Task task(String name, Closure configureClosure);

用法如下,有的小伙伴就有意见了,这个和上面的原型不一样。

task createTask3 {
    description '任务创建方式3'
    group 'testTaskCreate'
    doLast{
        println '第三种创建方法'
    }
}

我做一下解释哈,其中闭包Closure如果是最后一个参数可以移到外面,方法的参数可以不用加括号,这个都是Groovy的语法糖。如果你高兴也可以这样写:

task(createTask3) {
    description '任务创建方式3'
    group 'testTaskCreate'
    doLast{
        println '第三种创建方法'
    }
}

也可以这样写:

task(createTask3,  {
    description '任务创建方式3'
    group 'testTaskCreate'
    doLast{
        println '第三种创建方法'
    }
})

运行方式:

gradle createTask3
:createTask3
第三种创建方法

BUILD SUCCESSFUL

Total time: 0.889 secs
1.4第四种创建方式

第四种就是通过TaskContainer来创建,简单看下对TaskContainer的解释,TaskContainer其实就是用来管理task集合的,可以在project中通过getTask()方法来拿到这个实例,或者直接通过tasks来或者这个实例。

/**
 * <p>A {@code TaskContainer} is responsible for managing a set of {@link Task} instances.</p>
 *
 * <p>You can obtain a {@code TaskContainer} instance by calling {@link org.gradle.api.Project#getTasks()}, or using the
 * {@code tasks} property in your build script.</p>
 */
public interface TaskContainer extends TaskCollection<Task>, PolymorphicDomainObjectContainer<Task> 
Task create(String name, Closure configureClosure) throws InvalidUserDataException;

用法如下,这个也是把闭包挪到外面了,见上面语法糖。

tasks.create('createTask4'){
    description '任务创建方式4'
    group 'testTaskCreate'
    doLast{
        println '第四种创建方法'
    }
}

运行效果:

$ gradle createTask4
:createTask4
第四种创建方法

BUILD SUCCESSFUL

Total time: 0.825 secs

一般在Android中构建用第三种简化方式会比较多一点。

那么在project中怎么访问这个任务?
主要有两种方式,第一种方式就是先定义:

def Task myTask = task groupTask
myTask.group = BasePlugin.BUILD_GROUP
myTask.description = '这是一个构建的引导任务'

myTask.doLast {
    println "group: $group, description:$description"
}

另外一种方式就是通过TaskContainer来获取:

def Task myTask = task groupTask
tasks['groupTask'].doLast {
    println "group: $group, description:$description"
}

2.Task的常用属性

部分常用属性在前面已经有用到过了,dependsOn就是taskProperty这个依赖另外的task;group就是分组;description就是这个task的描述。

task helloTask{
    println 'hello'
}

task worldTask{
    println 'world!'
}

def Task myTask = task taskProperty{
    dependsOn helloTask, worldTask
    println 'in myTask'
}
myTask.group = BasePlugin.BUILD_GROUP
myTask.description = '测试常用属性'

我们看下执行结果,首先先执行依赖的Task:

$ gradle taskProperty
hello
world!
in myTask
:helloTask UP-TO-DATE
:worldTask UP-TO-DATE
:taskProperty UP-TO-DATE

BUILD SUCCESSFUL

再看下这个Task的信息,可以看到上面设置的属性生效了:

$ gradle help --task taskProperty
hello
world!
in myTask
:help
Detailed task information for taskProperty

Path
     :taskProperty

Type
     Task (org.gradle.api.Task)

Description
     测试常用属性

Group
     build

BUILD SUCCESSFUL

另外一个和dependsOn类似的属性就是mustRunAfter,这个运行结果和上面是一样的,就不贴出来了,小伙伴们可以自行试一下。

myTask.mustRunAfter = [helloTask, worldTask]

还有一个属性enabled可以启用或者禁用任务,默认是true,表示启用。设置为false,则禁止该任务执行,输出会提示任务被跳过:

task helloTask{
    println 'hello'
}
helloTask.enabled = false

task worldTask{
    println 'world!'
}

def Task myTask = task taskProperty{
    dependsOn helloTask, worldTask
    println 'in myTask'
}

输出结果,可以看到helloTask 提示SKIPPED

$ gradle taskProperty
hello
world!
in myTask
:helloTask SKIPPED
:worldTask UP-TO-DATE
:taskProperty UP-TO-DATE

BUILD SUCCESSFUL

另外一个比较常用的属性是onlyIf,它可以接受一个闭包作为参数,如果闭包返回true则执行该任务,否则跳过。这个在Android里面可以用于多渠道打包:

final String BUILD_ALL = 'all'

task testOnlyIf{
    println '打包'
}

task build{
    dependsOn testOnlyIf
    group BasePlugin.BUILD_GROUP
    description '多渠道打包'
}

testOnlyIf.onlyIf{
    def execute = false
    if (project.hasProperty('build')) {
        Object buildApps = project.property('build')
        if (BUILD_ALL.equals(buildApps)) {
            execute = true
        }else{
            execute = false
        }
    }else{
        execute = false
    }
    execute
}

在执行的时候就可以传入build属性值来决定testOnlyIf这个打包任务是否执行,如果我传入all就会执行testOnlyIf

$ gradle -Pbuild=all build
打包
:testOnlyIf UP-TO-DATE
:build UP-TO-DATE

BUILD SUCCESSFUL

如果传入不是 all 就不会执行这个Task:

$ gradle -Pbuild=Notall build
打包
:testOnlyIf SKIPPED
:build UP-TO-DATE

BUILD SUCCESSFUL

还有几个常用的属性doLastdoFirst在下面的执行顺序中一起说。

3.Task的执行分析

首先有个概念,配置在doFirst中的操作会首先执行,而配置在doLast中的会最后执行,执行顺序是doFirst,doSelf,doLast。我们看个例子:

def Task myTask = task createCustomTask(type: CustomTask){
    doFirst{
        println 'myTask执行之前执行doFirst'
    }
    doLast {
        println 'myTask执行之后执行doLast'
    }
}

class CustomTask extends DefaultTask{
    @TaskAction
    def doSelf(){
        println 'myTask执行doSelf'
    }
}

输出结果可以看出任务执行顺序跟我们的预期一致,type其实就是类似于继承,我们这里自定义一个Task:CustomTask,通过注解标注这个Task的需要做的任务。

$ gradle createCustomTask
:createCustomTask
myTask执行之前执行doFirst
myTask执行doSelf
myTask执行之后执行doLast

BUILD SUCCESSFUL

4.总结

今天关于Task的分享就到这里了,Task是Gradle中比较重要的知识点,我这里只是一些常用知识点的总结,希望对小伙伴们有点帮助哈。

文中有部分例子参考了Android Gradle权威指南,在此表示感谢!

最后,感谢@右倾倾的理解和支持。

以上。

欢迎关注公众号:JueCode

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容