原文:http://www.blogjava.net/wldandan/archive/2012/07/05/382246.htmlhtml
上一篇文章中,咱們提到了Gradle的一些基本概念,如Project、Task以及Action,而且建立了咱們的第一個Task。此次咱們來看看Gradle中關於Project和Task的更多細節。java
1. Project和Task服務器
對於build.gradle配置文件,當運行Gradle <Task> 時,Gradle會爲咱們建立一個Project的對象,來映射build.gradle中的內容。其中呢,對於不屬於任何Task範疇的代碼,Gradle會建立一個Script類的對象,來執行這些代碼;對於Task的定義,Gradle會建立Task對象,並將它會做爲project的屬性存在(其實是經過getTaskName完成的)。ok,看一個簡單的例子:閉包
新建文件basic/build.gradle,而後加入以下部分代碼:gradle
println "the project name is $name" task hello << { println "the current task name is $name" println "hello world" }
當運行這個例子時,首先Gradle會建立一個Porject的對象,而後將它和build.gradle的內容映射起來。在這個例子中,project包括兩部分:ui
1)可執行腳本定義spa
按照以前提到的,可執行腳本的定義將直接被建立成對應的Script類的對象
在這個例子中,Script對應的部分就是第一行println的部分,而後執行的結果就是打印出 "the project name is basic"。
默認的,Project的名字是當前build.gradle所在目錄的名字,在這個例子中,build.gradle放在basic目錄下,所以,project的name也就是basic..net
2)Task定義設計
在這個例子中,Gradle將建立一個Task的實例,將其和定義的task內容關聯起來。另外,按照以前所說的,當Gradle運行時,咱們可使用訪問project屬性的方式去訪問它。code
例如,這個例子中,咱們可使用project.hello來訪問這個task。由於這個task hello已經成爲project的一個屬性,那麼當咱們使用gradle properties(properties是gradle自帶的一個Task,它能列出當前project級別的全部屬性,可使用gradle tasks查看更多內建的Task)來獲取project級別的屬性列表時,也將會獲得'hello'。
另外,有一點要注意的是,在這個例子中,task中使用的$name,並非Project的name,它是當前Task的name,由於它被使用在Task的scope裏。
執行Gradle hello,輸出的結果將是:
current project name is test
the current task name is hello
hello world
2. 定義屬性
在Gradle中,咱們能夠定義如下三種屬性並使用它們:
1)System Properties
System Properties 實際是指的JVM的system properties。咱們知道,在運行java程序時,可使用-D來設置Java的系統變量,在Gradle中,你也能夠作一樣的事情。好比
gradle xxx -DmySystemProp=xxxx
同時,在build.gradle中,應該這樣使用這個變量:
task printSysProps << { println System.properties['system'] }
2)Project Properties
Project Properties是Gradle專門爲Project定義的屬性。它的最大優勢在於當運行gradle的時候,咱們可使用-P來設置它的值。好比,
gradle xxx -PmyProjectProp=xxxxx
而在build.gradle中,能夠這樣使用這個變量:
task printProps << { if (project.hasProperty('commandLineProjectProp')) { println commandLineProjectProp } }
同時,當咱們執行gradle properties查看屬性列表時,這個變量的名稱以及值會顯示在結果中。
3)Ext(ra) Properties
另外,咱們還能夠爲Project或者Task定義Ext屬性,也稱動態屬性,咱們必須使用關鍵字ext(對應ExtraPropertiesExtension的實例)去定義動態屬性。從這點能夠看出,Gradle已經爲咱們設計了不少不一樣的類,去作不一樣的事情,咱們只須要遵循Convention,使用他們便可。若是忘記寫ext關鍵字,gradle運行時則會提示:
"Dynamic properties are deprecated...."。這是由於之前版本的gradle定義動態屬性時,不須要加ext關鍵字的。
對於Project和Task而言,動態屬性定義的方式徹底同樣,只是做用域不同。
當定義完成後,咱們就可使用project.prop 或者 task.prop來訪問這些動態屬性了。下面讓咱們看一個例子:
ext.projectProperties="ext projectProperties-value" task printExtProps << { ext.taskProperties="ext.task.properties-value" if (project.hasProperty('projectProperties')){ println "ext.projectProperties values is " + projectProperties } if (printExtProps.hasProperty('taskProperties')){ println "task has defined ext.taskProperties value is " + taskProperties } }
注意:,對於ext定義的動態屬性,並不能經過外部的方式修改它的值,只能在build.gradle中去設置或者修改它的值。
同時,若是是爲project定義的ext動態屬性,也會顯示在gradle properties的結果中。
3. Task依賴
當構建一個複雜的項目時,不一樣task之間存在依賴是必然的。好比說,若是想運行'部署'的task,必然要先運行 編譯、打包、檢測服務器等task,只有當這被些被依賴的task執行完成後,纔會部署。對於這種行爲之間的依賴,Ant、Maven都提供了聲明式的定義,很是簡單。一樣,使用Gradle定義task之間的依賴也是件很容易的事。
例如,定義以下兩個Task,而且在"intro"里加上"dependendsOn"的關鍵字,以下所示:
task hello << { println 'Hello world!' } task intro(dependsOn: hello) << { println "I'm Gradle" }
執行 "gradle intro",結果將是:
Hello World I'm Gradle
因而可知,當執行gradle intro時,intro依賴的task hello會先被執行。除此以外,dependensOn也支持定義多個task的依賴,使用[]括起來便可。例如
task A(dependensOn:['B','C','D']) <<{ xxx }
除了使用dependensOn跟字符串來定義依賴,咱們也可使用taskX.dependensOn taskY這種形式:
task taskX << { println 'taskX' } task taskY << { println 'taskY' } taskX.dependsOn taskY
或者,也可使用閉包:
task taskX << { println 'taskX' } taskX.dependsOn { tasks.findAll { task -> task.name.startsWith('lib') } } task lib1 << { println 'lib1' }
除了以前講的task的部分,Gradle還爲咱們提供了不少可用的API,更多的細節你們能夠參考下Gradle的文檔。這裏我列出一個經常使用的方法onlyIf。在Gradle裏,咱們可使用「OnlyIf()」來決定當前task是否須要被執行,例如:新建build.gradle,加入以下代碼:
task hello << { println 'hello world' } hello.onlyIf { !project.hasProperty('skipHello') }
當咱們直接執行"gradle hello"時,沒有任何結果,當咱們執行"gradle hello -PskipHello=xxxx"時,會輸出"hello world"。
4. 總結OK.今天對gradle的總結到此爲止。整體而言,用DSL的代碼而不是xml來定義構建的過程,仍是很fancy的。