Gradle是以Groovy語言為基礎,基於DSL語法的自動化構建工具,一個構建腳本能夠包含任何Groovy語言元素,每個腳本都是UTF-8編碼的文件。
6-1 Project對象API
前面我們說過,Gradle在構建腳本中定義了一個project,對於構建腳本中每個project其實Gradle都創建了一個 Project類型的對象來關聯,當構建腳本執行時它會去配置所關聯的Project對象;構建腳本中每個被調用的方法和屬性都委托給了當前Project對象。
如下我們看一個使用Project屬性的例子:
println name println project.name
上面兩個println語句的輸出是一樣的;由於name屬性沒有在當前腳本中定義,所以可以像第一個那樣使用自動委托 ,通常我們使用第二中寫法。
Project對象提供了一些標准的屬性,我們可以在構建腳本中很方便的使用他們,如下:
| Name | Type | Default Value |
|---|---|---|
| project | Project | Project實例對象 |
| name | String | 項目目錄的名稱 |
| path | String | 項目的絕對路徑 |
| description | String | 項目描述 |
| projectDir | File | 包含構建腳本的目錄 |
| build | File | projectDir/build |
| group | Object | 未具體說明 |
| version | Object | 未具體說明 |
| ant | AntBuilder | Ant實例對象 |
具體關於Project的方法詳情參閱Project的API文檔。這里我們給出Project的apply方法的一個例子,如下:
//加載一個gradle文件 apply from: rootProject.getRootDir().getAbsolutePath() + "/common.gradle"
6-2 Script對象API
當Gradle執行一個腳本時它會將這個腳本編譯為實現了Script的類(在上篇博客《Groovy腳本基礎全攻略》Groovy的本質編譯class代碼那塊有介紹),也就是說所有的屬性和方法都是在Script的接口中聲明。
6-3 Gradle對象API
關於Gradle對象的詳細屬性和API介紹點我即可。這里直接給出一個使用Gradle對象的例子,如下:

6-4 Gradle變量聲明
在Gradle腳本中有兩種類型的變量可以聲明,如下:
- 局部變量
- 擴展變量
局部變量使用關鍵字def聲明,它只在聲明的地方可見,如下:
def dest = "dest" task copy(type: Copy) { form "source" into dest }
在Gradle中所有被增強的對象可以擁有自定義屬性(譬如projects、tasks、source sets等),使用ext擴展塊可以一次添加多個屬性。如下:
apply plugin: "java" ext { springVersion = "3.1.0.RELEASE" emailNotification = "build@master.org" } sourceSets.all { ext.purpose = null } sourceSets { main { purpose = "production" } test { purpose = "test" } plugin { purpose = "production" } } task printProperties << { println springVersion println emailNotification sourceSets.matching { it.purpose == "production" }.each { println it.name} }
上面我們用一個ext擴展塊向Project對象添加兩個擴展屬性,當這些擴展屬性被添加后,它們就像預定義的屬性一樣可以被讀寫。
6-5 Gradle中Groovy使用
這個沒啥說的,具體可以參考《Groovy腳本基礎全攻略》這篇博客,里面有詳細介紹。我們這里粗略總結回憶一下即可:
-
Groovy會自動將一個屬性的引用轉換為相應的getter/setter方法。
-
Groovy調用方法時圓括號可有可無。
-
Groovy為List和Map集合提供了一些操作捷徑,譬如apply plugin:’java’中的plugin:’java’其實就是Groovy中的Map,apply是一個方法,省略了括弧而已。
哎呀,詳細的還是去看前一篇博客吧。
【工匠若水 http://blog.csdn.net/yanbober 轉載請注明出處。點我開始Android技術交流】
7 Gradle文件操作基礎
實際使用Gradle過程中大多數時候需要操作文件,好在Gradle給我們提供了一些API來快捷處理。
定位文件:
我們可以使用Project.file()方法來定位一個文件獲取File對象(詳情參考Project的API),如下:
//相對路徑 File configFile = file('src/config.xml') //絕對路徑 File configFile = file(configFile.absolutePath) //項目路徑的文件對象 File configFile = file(new File('src/config.xml'))
可以從Project的API發現file()方法能夠接收任何形式的對象參數,它會將參數值轉換為一個絕對文件對象,通常我們可以傳一個String或File實例;如果傳的路徑是絕對路徑,則會被直接構造為一個文件實例,否則會被構造為項目目錄加上傳遞目錄的文件對象;當然了,file()方法還能識別URL(譬如file:/some/path.xml等)。
文件集合:
文件集合其實是一組文件,Gradle使用FileCollection接口表示文件集合,Gradle API中許多類都實現了這個接口,譬如dependency configurations等。獲取FileCollection實例的一種方法是Project.files(),我們可以傳遞任何數量的對象參數。如下:
FileCollection collection = files('src/file1.txt', new File('src/file2.txt'), ['src/file3.txt', 'src/file4.txt'])
使用迭代操作還能將其轉換為其他的一些類型,同時我們還可以使用+操作將兩個文件集合合並,使用-操作對一個文件集合做減法。如下例子:
// 對文件集合進行迭代
collection.each {File file -> println file.name } // 轉換文件集合為其他類型 Set set = collection.files Set set2 = collection as Set List list = collection as List String path = collection.asPath File file = collection.singleFile File file2 = collection as File // 增加和減少文件集合 def union = collection + files('src/file3.txt') def different = collection - files('src/file3.txt')
我們也可以向files()方法傳遞閉包或者可回調的實例參數,當查詢集合的內容時就會調用它,然后將返回值轉換為一些文件實例,返回值可以是files()方法支持的任何類型的對象。如下例子:
task list << {
File srcDir
// 使用閉合創建一個文件集合 collection = files { srcDir.listFiles() } srcDir = file('src') println "Contents of $srcDir.name" collection.collect { relativePath(it) }.sort().each { println it } srcDir = file('src2') println "Contents of $srcDir.name" collection.collect { relativePath(it) }.sort().each { println it } }
文件樹:
文件樹可以代表一個目錄樹結構或一個ZIP壓縮文件的內容,FileTree繼承自FileCollection,所以我們可以像處理文件集合一樣處理文件樹,使用Project.fileTree()方法可以得到FileTree實例,它會創建一個基於基准目錄的對象。如下:
/以一個基准目錄創建一個文件樹
FileTree tree = fileTree(dir: 'src/main') // 添加包含和排除規則 tree.include '**/*.java' tree.exclude '**/Abstract*' // 使用路徑創建一個樹 tree = fileTree('src').include('**/*.java') // 使用閉合創建一個數 tree = fileTree('src') { include '**/*.java' } // 使用map創建一個樹 tree = fileTree(dir: 'src', include: '**/*.java') tree = fileTree(dir: 'src', includes: ['**/*.java', '**/*.xml']) tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**') // 遍歷文件樹 tree.each {File file -> println file } // 過濾文件樹 FileTree filtered = tree.matching { include 'org/gradle/api/**' } // 合並文件樹A FileTree sum = tree + fileTree(dir: 'src/test') // 訪問文件數的元素 tree.visit {element -> println "$element.relativePath => $element.file" }
我們還可以使用ZIP或TAR等壓縮文件的內容作為文件樹,Project.zipTree()和Project.tarTree()方法可以返回一個FileTree實例。如下:
// 使用路徑創建一個ZIP文件 FileTree zip = zipTree('someFile.zip') // 使用路徑創建一個TAR文件 FileTree tar = tarTree('someFile.tar') //TarTree可以根據文件擴展名得到壓縮方式,如果我們想明確的指定壓縮方式則可以如下操作 FileTree someTar = tarTree(resources.gzip('someTar.ext'))
指定輸入文件:
Gradle中有些對象的屬性可以接收一組輸入文件,譬如JavaComplile任務的source屬性(定義編譯的源文件)。如下:
//使用一個File對象設置源目錄 compile { source = file('src/main/java') } //使用一個字符路徑設置源目錄 compile { source = 'src/main/java' } //使用一個集合設置多個源目錄 compile { source = ['src/main/java', '../shared/java'] } //使用FileCollection或者FileTree設置源目錄 compile { source = fileTree(dir: 'src/main/java').matching {include 'org/gradle/api/**'} } //使用閉包設置源目錄 compile { source = { // Use the contents of each zip file in the src dir file('src').listFiles().findAll {it.name.endsWith('.zip')}.collect { zipTree(it) } } } compile { //使用字符路徑添加源目錄 source 'src/main/java', 'src/main/groovy' //使用File對象添加源目錄 source file('../shared/java') //使用閉包添加源目錄 source { file('src/test/').listFiles() } }
復制文件:
我們可以使用復制任務(Copy)進行文件復制操作,復制任務擴展性很強,它可以過濾復制文件的內容,使用復制任務要提供想要復制的源文件和一個目標目錄,如果要指定文件被復制時的轉換方式則可以使用復制規則,復制規則是一個CopySpec接口的實現,我們使用CopySpec.from()方法指定源文件,CopySpec.into()方法指定目標目錄即可。如下:
task copyTask(type: Copy) {
from 'src/main/webapp' into 'build/explodedWar' } task anotherCopyTask(type: Copy) { //復制src/main/webapp目錄下的所有文件 from 'src/main/webapp' //復制一個單獨文件 from 'src/staging/index.html' //復制一個任務輸出的文件 from copyTask //顯式使用任務的outputs屬性復制任務的輸出文件 from copyTaskWithPatterns.outputs //復制一個ZIP壓縮文件的內容 from zipTree('src/main/assets.zip') //指定目標目錄 into { getDestDir() } } task copyTaskWithPatterns(type: Copy) { from 'src/main/webapp' into 'build/explodedWar' include '**/*.html' include '**/*.jsp' exclude { details -> details.file.name.endsWith('.html') && details.file.text.contains('staging') } } task copyMethod << { copy { from 'src/main/webapp' into 'build/explodedWar' include '**/*.html' include '**/*.jsp' } } //在復制時重命名文件 task rename(type: Copy) { from 'src/main/webapp' into 'build/explodedWar' //使用閉包映射文件名 rename { String fileName -> fileName.replace('-staging-', '') } // 使用正則表達式映射文件名 rename '(.+)-staging-(.+)', '$1$2' rename(/(.+)-staging-(.+)/, '$1$2') }
文件同步任務:
同步任務(Sync)繼承自復制任務(Copy),當執行時會復制源文件到目標目錄,然后從目標目錄刪除所有非復制文件。如下:
task libs(type: Sync) { from configurations.runtime into "$buildDir/libs" }
創建歸檔文件:
使用歸檔任務可以創建Zip、Tar、Jar、War、Ear等歸檔文件,如下:
apply plugin: 'java' task zip(type: Zip) { from 'src/dist' into('libs') { from configurations.runtime } }
ps:http://blog.csdn.net/yanbober/article/details/49314255
