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