轉(zhuǎn)自:http://www.cnblogs.com/davenkin/p/gradle-learning-4.html
請通過以下方式下載本系列文章的Github示例代碼:
git clone https://github.com/davenkin/gradle-learning.git
如果我們將Gradle的Task看作一個黑盒子兼吓,那么我們便可以抽象出輸入和輸出的概念凰慈,一個Task對輸入進行操作妈橄,然后產(chǎn)生輸出眉踱。比如谦炒,在使用java插件編譯源代碼時裸删,輸入即為Java源文件兼呵,輸出則為class文件满败。如果多次執(zhí)行一個Task時的輸入和輸出是一樣的贴铜,那么我們便可以認為這樣的Task是沒有必要重復(fù)執(zhí)行的粪摘。此時,反復(fù)執(zhí)行相同的Task是冗余的绍坝,并且是耗時的徘意。
為了解決這樣的問題,Gradle引入了增量式構(gòu)建的概念轩褐。在增量式構(gòu)建中椎咧,我們?yōu)槊總€Task定義輸入(inputs)和輸入(outputs),如果在執(zhí)行一個Task時,如果它的輸入和輸出與前一次執(zhí)行時沒有發(fā)生變化勤讽,那么Gradle便會認為該Task是最新的(UP-TO-DATE)蟋座,因此Gradle將不予執(zhí)行。一個Task的inputs和outputs可以是一個或多個文件脚牍,可以是文件夾向臀,還可以是Project的某個Property,甚至可以是某個閉包所定義的條件诸狭。
每個Task都擁有inputs和outputs屬性券膀,他們的類型分別為TaskInputs和TaskOutputs。在下面的例子中驯遇,我們展示了這么一種場景:名為combineFileContent的Task從sourceDir目錄中讀取所有的文件三娩,然后將每個文件的內(nèi)容合并到destination.txt文件中。讓我們先來看看沒有定義Task輸入和輸出的情況:
task combineFileContentNonIncremental {
????def sources = fileTree('sourceDir')
????def destination = file('destination.txt')
????doLast {
????????destination.withPrintWriter {writer ->
????????????sources.each {source ->
????????????????writer.println source.text
????????????}
????????}
????}
}
多次執(zhí)行“gradle combineFileContentNonIncremental”時妹懒,整個Task都會反復(fù)執(zhí)行雀监,即便在第一次執(zhí)行后我們已經(jīng)得到了所需的結(jié)果。如果該combineFileContentNonIncremental是一個繁重的Task眨唬,那么多次重復(fù)執(zhí)行勢必造成沒必要的時間耗費会前。
這時,我們可以將sources聲明為該Task的inputs匾竿,而將destination聲明為outputs瓦宜,重新創(chuàng)建一個Task如下:
task combineFileContentIncremental {
????def sources = fileTree('sourceDir')
????def destination = file('destination.txt')
????inputs.dir sources
????outputs.file destination
????doLast {
????????destination.withPrintWriter { writer ->
????????????sources.each {source ->
????????????????writer.println source.text
????????????}
????????}
????}
}
相比之下,后一個Task只比前一個Task多了兩行代碼:
inputs.dir sources
outputs.file destination
當首次執(zhí)行combineFileContentIncremental時岭妖,Gradle會完整地執(zhí)行該Task临庇。但是緊接著再執(zhí)行一次,命令行顯示:
:combineFileContentIncremental UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.104 secs
我們發(fā)現(xiàn)昵慌,combineFileContentIncremental被標記為UP-TO-DATE假夺,表示該Task是最新的,Gradle將不予執(zhí)行斋攀。在實際應(yīng)用中已卷,你將遇到很多這樣的情況,因為Gradle的很多插件都引入了增量式構(gòu)建機制淳蔼。
如果我們修改了inputs(即sourceDir文件夾)中的任何一個文件或刪除掉了destination.txt侧蘸,當調(diào)用“gradle combineFileContentIncremental”時,Gradle又會重新執(zhí)行鹉梨,因為此時的Task已經(jīng)不再是最新的了讳癌。對于outputs,我們還可以使用upToDateWhen()方法來決定一個Task的outputs是否為最新的存皂,該方法接受一個閉包作為檢查條件晌坤,感興趣的讀者可以自行了解。
在下一篇文章中,我們將講到如何自定義Project的Property泡仗。