1、項目(project)和任務(task)
Gradle中的任何事都基于兩個基本概念:項目(project)和任務(task)
每一個建構(build)都是由一個或多個項目組成的。一個項目代表什麼取決于你使用Gradle做什麼。例如,一個項目也許代表一個庫或者一個web應用程式,它也許代表一個由其他項目産生的JAR檔案組成的ZIP。一個工程不一定代表一件要去建構的事,它也許代表一件要去做的事情,例如将你的應用程式部署到工作台或者生産環境。現在看來,這些概念似乎有一點模糊,不過别擔心,Gradle的基于約定的建構會對一個項目是什麼有更具體的定義。
每一個項目由一個或多個任務(task)組成,一個任務代表一些執行建構工作的最小工作單元。它也許編譯一些類,建立一個JAR,生成Javadoc文檔,或者向庫釋出一些文檔。

一個build包含多個project,一個project包含多個task
現在,我們将在一個項目中定義一些簡單的任務,後面的章節将會使用多個項目,并且還有更多關于使用項目和任務的知識。
2、Hello World
你可以使用gradle指令運作Gradle的建構。gradle指令在目前目錄下查找一個名為build.gradle的檔案,我們稱build.gradle檔案是一個“建構腳本”,嚴格的說它是一個建構配置腳本。建構腳本定義了一個項目及其任務。
試一試:建立如下建構腳本,并命名為“build.gradle”
task hello{
doLast{
println 'Hello World!'
}
}
在控制台中移動到此檔案所在目錄,并輸入“gradle -q hello”執行該檔案,可看到控制台中輸出Hello World。
(關于 -q :使用者手冊中的大多數例子都使用了 -q 指令行選項,它會抑制Gradle的日志資訊,是以會隻顯示task的輸出。這會使手冊中例子的輸出更簡潔,你完全可以不使用它。)
對build.gradle的說明:建構腳本定義了一個名為“hello”的task,并為其添加了一個操作。當你運作“gradle hello”的時候,Gradle執行這個名為“hello”的task時,會去執行你提供的操作。這個操作是一個閉包,包含了Groovy代碼去執行。
3、使用更簡單/快捷的定義方式定義task
task hello << {
println 'Hello World!'
}
如上,這使用了 [一個簡單的閉包(翻譯不恰當)] 定義了一個名為“hello”的task,我們将在使用者手冊中使用這種風格定義task
4、建構腳本代碼
Gradle的建構腳本給你Groovy的全部權利。
例1:在名為“build.gradle”的檔案中輸入如下代碼:
task upper <<{
String str = 'aBcD'
println "original:" + str
println "Upper case:" + str.toUpperCase()
}
運作結果如下:
例2:在名為“build.gradle”的檔案中輸入如下代碼:
task count << {
.times { print "$it " }
println ''
}
結果如下:
5、task依賴
也許你已經猜到了,你可以聲明依賴于其他tasks的task
例:在名為“build.gradle”的檔案中輸入如下代碼:
task hello << {
println "hello"
}
task world(dependsOn: hello) <<{
println "world"
}
結果如下:
可見,若先執行名為hello的task,則會隻執行該task;若先執行名為world的task,則會先執行該task所依賴的其他task(hello),然後再執行自身那個task。即,被依賴的task會先執行。
懶依賴:被依賴的task不存在(被依賴的task後定義)
task world(dependsOn: "hello") <<{
println "world"
}
task hello << {
println "hello"
}
注意:task world依賴的task的名字要加上引号
結果如下:
Task world對task hello的依賴關系聲明在task hello定義之前,這對于多項目建構非常重要。
請注意,當引用一個未被定義的task時,你不能使用 shortcut notation (即點運算符 . )
6、動态task
Groovy能不僅能用于指定一個task能做什麼,你也能用它去動态建立task。
.times{ counter ->
task "task$counter" <<{
println "No. $counter task"
}
}
結果如下:
7、操作現有的task
一旦task被建立,他們就能通過API被通路到。
例如,你可以在運作時動态地為task添加依賴關系。
.times{ counter ->
task "task$counter" <<{
println "No. $counter task"
}
}
task1.dependsOn task2, task3
為task1添加對task2,task3的依賴。
結果如下:
為現有的task添加行為:
task hello <<{
println "hello"
}
hello.doFirst{
println "doFirst"
}
hello.doLast{
println "doLast"
}
hello << {
println '88888'
}
結果如下:
可見,執行的順序為:doFirst - task本身 - doLast - <<(doLast)
doFirst和doLast可以被多次調用,doFirst在task的操作清單開頭,doLast在task的操作清單結尾,當task執行時,操作清單中的操作會按順序執行。
“<<”操作符隻不過是doLast的别名。
8、快捷通路符(. )
也許你已經注意到,可以使用快捷通路符通路現存的task,建構腳本中的每一個task的屬性都可以使用快捷通路符通路。
task hello <<{
println "hello world"
}
hello.doLast{
println "my name is $hello.name !"
}
結果如下:
這使得代碼很易讀,特别是當使用插件提供的task時,例如編譯task(compile task)
9、額外的task屬性
你可以為task添加你自己的屬性。
添加一個名為“myProperty”的屬性,并為其賦初值。從這時起,這個屬性就能像一個預定義的task屬性一樣讀、寫(設定)
task myTask {
ext.myProperty = "Xiaming_Chen"
}
task printMyProperty <<{
println myTask.myProperty
myTask.myProperty = "Chen_Xiaming"
println myTask.myProperty
}
結果如下:
可見,額外的task屬性不局限于task,myProperty屬性可以被其他的task讀,也能在其他task中為其指派。
10、使用Ant tasks
11、使用方法
在Gradle中,你可以怎樣組織你的建構邏輯是有等級限制的。上面的示例“提取一個方法”隻是第一級。
12、預設task
如果你沒有指定其他的task,Gradle允許你定義一個或多個預設task執行。
defaultTasks "default1","default2"
task default1<<{
println "No.1 default task"
}
task default2<<{
println "No.2 default task"
}
task myTask<<{
println "my task"
}
結果如下:
指定預設task為default1和default2,當執行時若不指定要執行的task,則會執行所有預設的task。
這與運作“gradle default1 default2”等效。
在一個多項目建構中,每個子項目能擁有他們自己特定的預設task,如果一個子項目沒有指定預設task,則父項目的預設task會被使用(如果定義了的話)。
13、用DAG配置Gradle有配置階段和執行階段,在配置階段之後,Gradle知道所有需要被執行的task,Gradle為你提供了可以利用這些資訊的工具。一個用例将會檢查釋出的task是否在要被執行的所有task中,由此,你可以為不同的變量配置設定不同的值。
在下面的例子中,task的執行結果會因變量version的不同而不同。
task distribution <<{
println "We build the zip with version = $version"
}
task release(dependsOn: distribution) <<{
println "We release now"
}
gradle.taskGraph.whenReady { taskGraph ->
if(taskGraph.hasTask(release)){
version = "1.0"
}else{
version = "1.0-SNAPSHOT"
}
}
執行gradle -q distribution:
執行gradle -q release:
“whenReady”會在release task執行之前影響release,即使release task不是首要的task這也會起作用。