【轉】從零開始學習Gradle之二---如何使用Task

原文: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的。

相關文章
相關標籤/搜索