Gradle基礎(chǔ)(一) 定義Task or創(chuàng)建task多種方法

1.Gradle的Project從本質(zhì)上說(shuō)只是含有多個(gè)Task的容器,一個(gè)Task與Ant的Target相似,表示一個(gè)邏輯上的執(zhí)行單元。我們可以通過(guò)很多種方式定義Task,所有的Task都存放在Project的TaskContainer中。

2.Task可以理解為Gradle的執(zhí)行單元,實(shí)在是太重要了。根據(jù)前面的分析,Gradle通過(guò)一個(gè)個(gè)task來(lái)完成具體的構(gòu)建任務(wù),下面我們來(lái)看下Task的定義。

(1)調(diào)用Project的task()方法創(chuàng)建Task
 在使用Gradle時(shí),創(chuàng)建Task最常見(jiàn)的方式便是:

task helloWord << {
    println 'Hello World! Charles'
}

這里的“<<”表示追加的意思,即向hello中加入執(zhí)行過(guò)程。我們還可以使用doLast來(lái)達(dá)到同樣的效果:

task hello2 {
    doLast {
        println 'hello2'}
}

另外,如果需要向Task的最前面加入執(zhí)行過(guò)程,我們可以使用doFirst:
task hello3 {
    doFirst {
        println 'hello3'}
}

除此之外,doLast還有一個(gè)等價(jià)的操作leftShift,leftShift還可以縮寫(xiě)為<<,因此下這三種實(shí)現(xiàn)效果等價(jià)
helloWord .leftShift {
    println 'Hello World! Charles--left'
}

在上面的例子中,Gradle的DSL向我們展示了一種非常自然的風(fēng)格來(lái)創(chuàng)建Task,而事實(shí)上這些都只是一種內(nèi)部DSL,也即必須符合groovy的語(yǔ)法要求。上面的task關(guān)鍵字實(shí)際上是一個(gè)方法調(diào)用,該方法屬于Project。Project中存在多個(gè)重載的task()方法。和Ruby等動(dòng)態(tài)語(yǔ)言一樣,在調(diào)用groovy方法時(shí),我們不用將參數(shù)放在括號(hào)里面。
以上我們自定義的Task都位于TaskContainer中,Project中的tasks屬性即表示該TaskContainer。為此,我們可以新建一個(gè)Task來(lái)顯示這些信息:

task showTasks {
    println tasks.class
    println tasks.size()
}

將以上4個(gè)Task放在同一個(gè)build.gradle中,再執(zhí)行g(shù)radle showTasks,命令行輸出如下:

...
class org.gradle.api.internal.tasks.DefaultTaskContainer_Decorated
4
...

上面的DefaultTaskContainer_Decorated表示tasks類(lèi)型,而4表示該TaskContainer中包含有4個(gè)自定義的Task——包括showTasks本身。

(2)通過(guò)TaskContainer的create()方法創(chuàng)建Task而Project又維護(hù)了一個(gè)TaskContainer類(lèi)型的屬性tasks,那么我們完全可以直接向TaskContainer里面添加Task。查查T(mén)askContainer的API文檔可以發(fā)現(xiàn),TaskContainer向我們提供了大量重載的create()方法用于添加Task。

tasks.create(name:'hello4') <<{
    println 'hello4'
}

(3)聲明Task之間的依賴(lài)關(guān)系
Task之間是可以存在依賴(lài)關(guān)系,比如TaskA依賴(lài)TaskB,那么在執(zhí)行TaskA時(shí),Gradle會(huì)先執(zhí)行TaskB,再執(zhí)行TaskA。我們可以在定義一個(gè)Task的同時(shí)聲明它的依賴(lài)關(guān)系:

task hello5(dependsOn:hello4) << {
    println 'hello5'
}

當(dāng)然,我們也可以在定義Task之后再聲明依賴(lài):

task hello6 << {
    println 'hello6'
}

hello6.dependsOn hello5

(4)配置Task
一個(gè)Task除了執(zhí)行操作之外,還可以包含多個(gè)Property,其中有Gradle為每個(gè)Task默認(rèn)定義的Property,比如description,logger等。另外,每一個(gè)特定的Task類(lèi)型還可以含有特定的Property,比如Copy的from和to等。當(dāng)然,我們還可以動(dòng)態(tài)地向Task中加入額外的Property。在執(zhí)行一個(gè)Task之前,我們通常都需要先設(shè)定Property的值,Gradle提供了多種方法設(shè)置Task的Property值。

首先,我們可以在定義Task的時(shí)候?qū)roperty進(jìn)行配置:

task hello7 << {
    description = "this is hello7"
    println description
}

我們還可以通過(guò)閉包的方式來(lái)配置一個(gè)已有的Task:

task hello8 << {
    println description
}

hello8 {
    description = "this is hello8"
}

需要注意的是,對(duì)hello8的description設(shè)置發(fā)生在創(chuàng)建該Task之后,在執(zhí)行“gradle hello8”時(shí),命令行依然可以打印出正確的“this is hello8”,這是因?yàn)镚radle在執(zhí)行Task時(shí)分為兩個(gè)階段,首先是配置階段,然后才是實(shí)際執(zhí)行階段。所以在執(zhí)行hello8之前,Gradle會(huì)掃描整個(gè)build.gradle文檔,將hello8的description設(shè)置為“this is hello8”,然后執(zhí)行hello8,此時(shí)hello8的description已經(jīng)包含了設(shè)置后的值。

我們還可以通過(guò)調(diào)用Task的configure()方法完成Property的設(shè)置:

task hello9 << {
    println description
}

hello9.configure {
    description = "this is hello9"
}

實(shí)際上,通過(guò)閉包的方式配置Task在內(nèi)部也是通過(guò)調(diào)用Task的configure()方法完成的

(5)group task屬于哪個(gè)組下面我來(lái)看一個(gè)列子

// 定義一個(gè)名字為Cls的task,屬于Charles分組,并且依賴(lài)myTask1和myTask2兩個(gè)task。
project.task('ClsTask', group: "charles", description: "我自己的Task", dependsOn: ["myTask1", "myTask2"] ).doLast {
    println "execute ClsTask"
}

嘗試執(zhí)行g(shù)radle ClsTask,結(jié)果如下:

:myTask1
execute myTask1
:myTask2
execute myTask2
:ClsTask
execute ClsTask

BUILD SUCCESSFUL

(6)定義Task的時(shí)候是可以指定很多參數(shù)的,如下所示:

參數(shù)                     含義                       默認(rèn)值
name                   task的名字              不能為空,必須指定
type                   task的“父類(lèi)”              DefaultTask
overwrite             是否替換已經(jīng)存在的task         false
dependsOn             task依賴(lài)的task的集合            []
group                   task屬于哪個(gè)組               null
descriptions             task的描述                  null
 

到此 Gradle 定義Task就全部講完。最后,定義task的API很多,我介紹了最常用的部分,剩下的細(xì)節(jié)還是需要大家查看Gradle文檔,其實(shí)學(xué)習(xí)Gradle就是一個(gè)查文檔的過(guò)程。如下幾個(gè)文檔,大家讀讀。
Project API

TaskContainer API

Task API

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容