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閱讀 228,412評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,514評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,373評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,975評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,743評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,199評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,414評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,951評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,780評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,218評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,649評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,889評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,673評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容