Android Gradle学习(二):如何创建Task

一个 Task 是 Gradle 里项目构建的原子执行单元,Gradle 通过将一个个Task串联起来完成具体的构建任务,每个 Task 都属于一个 Project。关于 Task 的具体定义可查看官方文档Gradle Task API

1. 在Gradle里定义Task

在 build.gradle 里可以通过 task 关键字来创建Task:

task myTask
task myTask { configure closure }
task myTask(type: SomeType)
task myTask(type: SomeType) { configure closure }

我们来试验一下,新建一个 build.gradle 文件,在里面创建2个最简单的task:

task myTask1 {
    println "configure task1"
}

task myTask2 {
    println "configure task2"
}

执行其中一个task:gradle myTask1

> Configure project :
configure task1
configure task2

上面定义了2个 task :myTask1、myTask2,但是当我们执行 myTask1 时,发现2个 task 括号内部的代码都被执行了。括号内部的代码我们称之为配置代码,在 gradle 脚本的配置阶段都会执行,也就是说不管执行脚本里的哪个任务,所有 task 里的配置代码都会执行。这似乎与我们的期望不一致,通常我们写程序时调用一个方法,这个方法里的代码才会执行,那么我们执行一个 Task 时,这个 Task 里的代码才会被执行才对啊。显然 Gradle 里是不一样的,这个问题就涉及到 Task Action 的概念了。

2. Task Actions

一个 Task 是由一序列 Action (动作)组成的,当运行一个 Task 的时候,这个 Task 里的 Action 序列会按顺序依次执行。前面例子括号里的代码只是配置代码,它们并不是 Action ,Task 里的 Action 只会在该 Task 真正运行时执行,Gralde 里通过 doFirst、doLast 来为 Task 增加 Action 。

  • doFirst:task执行时最先执行的操作
  • doLast:task执行时最后执行的操作
task myTask1 {
    println "configure task1"
}

task myTask2 {
    println "configure task2"
}

myTask1.doFirst {
    println "task1 doFirst"
}

myTask1.doLast {
    println "task1 doLast"
}

myTask2.doLast {
    println "task2 doLast
}

同样执行myTask1:gradle myTask1,这次的结果如下:

> Configure project :
configure task1
configure task2

> Task :myTask1
task1 doFirst
task1 doLast

从上面例子中可以看到,所有 Task 的配置代码都会运行,而 Task Actions 则只有该 Task 运行时才会执行。

3. doLast等价操作

doLast有一种等价操作叫做leftShift,leftShift可以缩写为 << ,下面几种写法效果是一模一样的:

myTask1.doLast {
    println "task1 doLast"
}

myTask1 << {
    println "task1 doLast<<"
}

myTask1.leftShift {
    println "task1 doLast leftShift"
}

需要注意的是 << 操作符,它只是一种 Gradle 里的语法糖而已,不要被这种写法迷惑了。

4. 创建Task的几种常见写法

task myTask1 {
    doLast {
        println "doLast in task1"
    }
}

task myTask2 << {
    println "doLast in task2"
}

//采用 Project.task(String name) 方法来创建
project.task("myTask3").doLast {
    println "doLast in task3"
}

//采用 TaskContainer.create(String name) 方法来创建
project.tasks.create("myTask4").doLast {
    println "doLast in task4"
}

project.tasks.create("myTask5") << {
    println "doLast in task5"
}

初次接触这些写法,头都是大的,Gradle太灵活了,个人觉得记住最常用的即可,看到类似写法能看懂就行了。

5. 创建Task的参数介绍

在 Gradle 中定义 Task 的时候,可以指定更多的参数,如下所示:

参数名 含义 默认值
name task的名字 必须指定,不能为空
type task的父类 默认值为org.gradle.api.DefaultTask
overwrite 是否替换已经存在的同名task false
group task所属的分组名 null
description task的描述 null
dependsOn task依赖的task集合
constructorArgs 构造函数参数

我们来测试下:

task myTask1 << {
    println "doLast in task1"
}

task myTask2 << {
    println "doLast in task2"
}

task myTask3 << {
    println "doLast in task3, this is old task"
}

task myTask3(description: "这是task3的描述", group: "myTaskGroup", dependsOn: [myTask1, myTask2], overwrite: true) << {
    println "doLast in task3, this is new task"
}

执行 gradle myTask3,结果如下:

> Task :myTask1
doLast in task1

> Task :myTask2
doLast in task2

> Task :myTask3
doLast in task3, this is new task

执行命令 gradle -q tasks --all,查看下 task 信息,节选我们创建的 task 信息如下:

MyTaskGroup tasks
------------
myTask3 - 这是task3的描述

Other tasks
-----------
myTask1
myTask2

上面例子中创建了2个名为 myTask3 的 task,但是后一个将前一个替换掉了,在分组信息里多了个一个名为 MyTaskGroup 的分组,其他没有命名分组的统一归到 Other 这个分组里去了。

我们再来看看 type 参数怎么个用法,在 Gradle 中通过 task 关键字创建的 task,默认的父类都是 org.gradle.api.DefaultTask,这里定义了一些 task 的默认行为。看看下面这个例子:

//自定义Task类,必须继承自DefaultTask
class SayHelloTask extends DefaultTask {
    
    String msg = "default name"
    int age = 18        

    //构造函数必须用@javax.inject.Inject注解标识
    @javax.inject.Inject
    SayHelloTask(int age) {
        this.age = age
    }

    //通过@TaskAction注解来标识该Task要执行的动作
    @TaskAction
    void sayHello() {
        println "Hello $msg ! age is ${age}"
    }

}

//通过constructorArgs参数来指定构造函数的参数值
task hello1(type: SayHelloTask, constructorArgs: [30])

//通过type参数指定task的父类,可以在配置代码里修改父类的属性
task hello2(type: SayHelloTask, constructorArgs: [18]) {
        //配置代码里修改 SayHelloTask 里的字段 msg 的值
    msg = "hjy"
}

执行这2个 task 查看运行结果如下:

> Task :hello1
Hello default name ! age is 30

> Task :hello2
Hello hjy ! age is 18

上面这个例子中,演示了如何自己创建一个 Task 类,这里只是一些最简单的用法,每个 Task 应该还有输入、输出等等,且待下章分解。

官方资料

Project API
TaskContainer API
Task API

系列文章

Android Gradle学习(一):Gradle基础入门
Android Gradle学习(二):如何创建Task
Android Gradle学习(三):Task进阶学习
Android Gradle学习(四):Project详解
Android Gradle学习(五):Extension详解
Android Gradle学习(六):NamedDomainObjectContainer详解
Android Gradle学习(七):Gradle构建生命周期
Android Gradle学习(八):统计Task执行时长
Android Gradle学习(九):一些有用的小技巧

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

推荐阅读更多精彩内容