Gradle學習系列之四——增量式構建

請通過以下方式下載本系列文章的Github示例代碼:

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



如果我們將Gradle的Task看作一個黑盒子,那麼我們便可以抽象出輸入和輸出的概念,一個Task對輸入進行操作,然後產生輸出。比如,在使用java插件編譯源代碼時,輸入即爲Java源文件,輸出則爲class文件。如果多次執行一個Task時的輸入和輸出是一樣的,那麼我們便可以認爲這樣的Task是沒有必要重複執行的。此時,反覆執行相同的Task是冗餘的,並且是耗時的。


爲了解決這樣的問題,Gradle引入了增量式構建的概念。在增量式構建中,我們爲每個Task定義輸入(inputs)和輸入(outputs),如果在執行一個Task時,如果它的輸入和輸出與前一次執行時沒有發生變化,那麼Gradle便會認爲該Task是最新的(UP-TO-DATE),因此Gradle將不予執行。一個Task的inputs和outputs可以是一個或多個文件,可以是文件夾,還可以是Project的某個Property,甚至可以是某個閉包所定義的條件。


每個Task都擁有inputs和outputs屬性,他們的類型分別爲TaskInputs和TaskOutputs。在下面的例子中,我們展示了這麼一種場景:名爲combineFileContent的Task從sourceDir目錄中讀取所有的文件,然後將每個文件的內容合併到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     }   }  }}
複製代碼


多次執行“gradle combineFileContentNonIncremental”時,整個Task都會反覆執行,即便在第一次執行後我們已經得到了所需的結果。如果該combineFileContentNonIncremental是一個繁重的Task,那麼多次重複執行勢必造成沒必要的時間耗費。


這時,我們可以將sources聲明爲該Task的inputs,而將destination聲明爲outputs,重新創建一個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 sourcesoutputs.file destination


當首次執行combineFileContentIncremental時,Gradle會完整地執行該Task。但是緊接着再執行一次,命令行顯示:

:combineFileContentIncremental UP-TO-DATEBUILD SUCCESSFULTotal time: 2.104 secs


我們發現,combineFileContentIncremental被標記爲UP-TO-DATE,表示該Task是最新的,Gradle將不予執行。在實際應用中,你將遇到很多這樣的情況,因爲Gradle的很多插件都引入了增量式構建機制。


如果我們修改了inputs(即sourceDir文件夾)中的任何一個文件或刪除掉了destination.txt,當調用“gradle combineFileContentIncremental”時,Gradle又會重新執行,因爲此時的Task已經不再是最新的了。對於outputs,我們還可以使用upToDateWhen()方法來決定一個Task的outputs是否爲最新的,該方法接受一個閉包作爲檢查條件,感興趣的讀者可以自行了解。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章