Gradle學(xué)習(xí)系列之四——增量式構(gòu)建

轉(zhuǎn)自:http://www.cnblogs.com/davenkin/p/gradle-learning-4.html

請(qǐng)通過(guò)以下方式下載本系列文章的Github示例代碼:

git clone https://github.com/davenkin/gradle-learning.git

如果我們將Gradle的Task看作一個(gè)黑盒子,那么我們便可以抽象出輸入和輸出的概念,一個(gè)Task對(duì)輸入進(jìn)行操作,然后產(chǎn)生輸出。比如,在使用java插件編譯源代碼時(shí),輸入即為Java源文件,輸出則為class文件。如果多次執(zhí)行一個(gè)Task時(shí)的輸入和輸出是一樣的,那么我們便可以認(rèn)為這樣的Task是沒(méi)有必要重復(fù)執(zhí)行的。此時(shí),反復(fù)執(zhí)行相同的Task是冗余的,并且是耗時(shí)的。

為了解決這樣的問(wèn)題,Gradle引入了增量式構(gòu)建的概念。在增量式構(gòu)建中,我們?yōu)槊總€(gè)Task定義輸入(inputs)和輸入(outputs),如果在執(zhí)行一個(gè)Task時(shí),如果它的輸入和輸出與前一次執(zhí)行時(shí)沒(méi)有發(fā)生變化,那么Gradle便會(huì)認(rèn)為該Task是最新的(UP-TO-DATE),因此Gradle將不予執(zhí)行。一個(gè)Task的inputs和outputs可以是一個(gè)或多個(gè)文件,可以是文件夾,還可以是Project的某個(gè)Property,甚至可以是某個(gè)閉包所定義的條件。

每個(gè)Task都擁有inputs和outputs屬性,他們的類型分別為TaskInputs和TaskOutputs。在下面的例子中,我們展示了這么一種場(chǎng)景:名為combineFileContent的Task從sourceDir目錄中讀取所有的文件,然后將每個(gè)文件的內(nèi)容合并到destination.txt文件中。讓我們先來(lái)看看沒(méi)有定義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”時(shí),整個(gè)Task都會(huì)反復(fù)執(zhí)行,即便在第一次執(zhí)行后我們已經(jīng)得到了所需的結(jié)果。如果該combineFileContentNonIncremental是一個(gè)繁重的Task,那么多次重復(fù)執(zhí)行勢(shì)必造成沒(méi)必要的時(shí)間耗費(fèi)。

這時(shí),我們可以將sources聲明為該Task的inputs,而將destination聲明為outputs,重新創(chuàng)建一個(gè)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

????????????}

????????}

????}

}

相比之下,后一個(gè)Task只比前一個(gè)Task多了兩行代碼:

inputs.dir sources

outputs.file destination

當(dāng)首次執(zhí)行combineFileContentIncremental時(shí),Gradle會(huì)完整地執(zhí)行該Task。但是緊接著再執(zhí)行一次,命令行顯示:

:combineFileContentIncremental UP-TO-DATE

BUILD SUCCESSFUL

Total time: 2.104 secs

我們發(fā)現(xiàn),combineFileContentIncremental被標(biāo)記為UP-TO-DATE,表示該Task是最新的,Gradle將不予執(zhí)行。在實(shí)際應(yīng)用中,你將遇到很多這樣的情況,因?yàn)镚radle的很多插件都引入了增量式構(gòu)建機(jī)制。

如果我們修改了inputs(即sourceDir文件夾)中的任何一個(gè)文件或刪除掉了destination.txt,當(dāng)調(diào)用“gradle combineFileContentIncremental”時(shí),Gradle又會(huì)重新執(zhí)行,因?yàn)榇藭r(shí)的Task已經(jīng)不再是最新的了。對(duì)于outputs,我們還可以使用upToDateWhen()方法來(lái)決定一個(gè)Task的outputs是否為最新的,該方法接受一個(gè)閉包作為檢查條件,感興趣的讀者可以自行了解。

在下一篇文章中,我們將講到如何自定義Project的Property。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容