Project
和Task
是Gradle
中最核心的兩個元素,當創建了一個build.gradle
腳本那么Gradle
便會依據腳本的配置創建一個Project
,而腳本中的Task
也會創建與之相對應DeafultTask
實現。
Gradle
通過一個個Task
來完成具體的構建任務 ,可以說Task
乃是Gradle
的核心。根據執行階段的不同,可以將Gradle
中Task
分為配置型Task
以及動作型Task
。
一、Task的基本組成
查看Task DSL
說明我們可以發現,通常一個Task
包括: 依賴、動作、屬性、輸入、輸出、終結器等構成。
當然這些并不是每一個都是必須的。創建任務的時候需要根據自己的具體需要進行選擇性配置。
二、定義Task
Gralde
中定義一個任務的方式十分靈活,下面都是定義一個任務的方式。
task myTask
task myTask { configure closure }
task myTask(type: SomeType)
task myTask(type: SomeType) { configure closure }
配置型Task
定義一個Task
十分簡單,只需要使用task name{}
即可定義一個簡單的任務。
task helloTask {
println "Hello World"
}
執行gradle hT
,可以觀察到執行結果。這里你可能會注意到Hello world
并非在執行階段開始執行的,而是在配置階段就已經打印了。沒錯,這就是一個配置型Task
,因為Gradle在任務執行前,總會去遍歷所有任務去生成一張DAG(有向無環圖)
來確定任務之間的關系。
動作型Task
如果不想讓任務在配置階段執行,那么可以參照如下方式,通過給任務添加action的方式使其在執行階段運行。
task helloTask {
doLast {
println "Hello World"
}
}
常用的action有兩個,doFirst
和doLast
,通過這兩個見名知意的action
可以用來定置化你的任務行為。
- 一個Task包含若干
Action
。所以,Task有doFirst
和doLast
兩個函數,用于添加需要最先執行的Action
和需要和需要最后執行的Action
。Action
就是一個閉包。 - Task創建的時候可以指定Type,通過type:名字表達。這是什么意思呢?其實就是告訴
Gradle
,這個新建的Task對象會從哪個基類Task派生。比如,Gradle本身提供了一些通用的Task,最常見的有Copy 任務。Copy是Gradle中的一個類。當我們:*task myTask(type:Copy)*
的時候,創建的Task就是一個Copy Task。 - 當我們使用
task myTask{ xxx}
的時候。花括號是一個closure
。這會導致gradle在創建這個Task之后,返回給用戶之前,會先執行closure的內容。
當用戶執行test任務時,執行以下步驟:
- 執行build.gradle,初始化任務,初始化步驟為2-7;
- 注冊test任務,任務體都是默認好的,不可更改,為打印冒號加任務名,所以test的任務體為
println ':test'
; - 每個任務都有一個隊列一個棧,一個是依賴隊列,一個是first棧,一個是last隊列;
- 遇到doFirst函數,該函數接受一個閉包作為參數,doFirst函數會把閉包參數放入first棧;
- 遇到doLast函數,同理doFirst函數,閉包參數會被放入last隊列;
- 然后遇到
println 'hello.'
,執行該指令//1; - 至此初始化過程完成。
- 開始執行test任務前,先檢查是否任務依賴,如果有,先把依賴的任務都執行完。
- 然后開始執行test任務;
- 執行時,首先執行test任務的任務體,即
println ':test'
; - 然后執行test任務的first棧//2和last隊列//3;
- 任務執行結束。