創建Task的多種方法



Gradle學習本系列上篇文章中,我們講到了Gradle入門,在本篇文章中我們將講到創建Task的多種方法。


請通過以下方式下載本系列文章的Github示例代碼:

git clone https://github.com/davenkin/gradle-learning.git




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



(1)調用Project的task()方法創建Task

在使用Gradle時,創建Task最常見的方式便是:

task hello1 << {  println 'hello1'}


這裏的“<<”表示追加的意思,即向hello中加入執行過程。我們還可以使用doLast來達到同樣的效果:

task hello2 {  doLast {   println 'hello2'}}


另外,如果需要向Task的最前面加入執行過程,我們可以使用doFirst:

task hello3 {  doLast {   println 'hello3'}}


在上面的3個例子中,Gradle的DSL向我們展示了一種非常自然的風格來創建Task,而事實上這些都只是一種內部DSL,也即必須符合groovy的語法要求。上面的task關鍵字實際上是一個方法調用,該方法屬於Project。Project中存在多個重載的task()方法。和Ruby等動態語言一樣,在調用groovy方法時,我們不用將參數放在括號裏面。

以上我們自定義的3個Task都位於TaskContainer中,Project中的tasks屬性即表示該TaskContainer。爲此,我們可以新建一個Task來顯示這些信息:

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


將以上4個Task放在同一個build.gradle中,再執行gradle showTasks,命令行輸出如下:

...class org.gradle.api.internal.tasks.DefaultTaskContainer_Decorated4...


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



(2)通過TaskContainer的create()方法創建Task
在上文中我們講到,通過task()方法創建的Task都被存放在了TaskContainer中,而Project又維護了一個TaskContainer類型的屬性tasks,那麼我們完全可以直接向TaskContainer裏面添加Task。查查TaskContainer的API文檔可以發現,TaskContainer向我們提供了大量重載的create()方法用於添加Task。

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



(3)聲明Task之間的依賴關係
Task之間是可以存在依賴關係,比如TaskA依賴TaskB,那麼在執行TaskA時,Gradle會先執行TaskB,再執行TaskA。我們可以在定義一個Task的同時聲明它的依賴關係:

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


當然,我們也可以在定義Task之後再聲明依賴:

task hello6 << {  println 'hello6'}hello6.dependsOn hello5



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

首先,我們可以在定義Task的時候對Property進行配置:

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


我們還可以通過閉包的方式來配置一個已有的Task:

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


需要注意的是,對hello8的description設置發生在創建該Task之後,在執行“gradle hello8”時,命令行依然可以打印出正確的“this is hello8”,這是因爲Gradle在執行Task時分爲兩個階段,首先是配置階段,然後纔是實際執行階段。所以在執行hello8之前,Gradle會掃描整個build.gradle文檔,將hello8的description設置爲“this is hello8”,然後執行hello8,此時hello8的description已經包含了設置後的值。

我們還可以通過調用Task的configure()方法完成Property的設置:

複製代碼
task hello9 << {  println description}hello9.configure {  description = "this is hello9"}
複製代碼


實際上,通過閉包的方式配置Task在內部也是通過調用Task的configure()方法完成的,對此我們將在後續的文章中詳細地講到。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章