學習本系列前可以下載相關的github項目gradleLearnDemo。
地址:https://github.com/sososeen09/gradleLearnDemo
Gradle的增量式構建特性緊緊的與生命周期相結合。Gradle的增量式構建支持自動鑒別不需要被運行的任務。這些任務會被標記為 UP-TO-DATE。特別是在大型的企業級項目,這個特性是節約時間的好幫手。
Gradle通過比較兩次構建task的inputs和outputs來決定task是否是最新的。自從最后一次task執行以來,如果inputs和outputs沒有發生變化,則認為task是最新的。
輸入可以是一個目錄、一個或多個文件,或者是一個任意屬性。
一個task的輸出是通過一個目錄或1~n個文件來定義的。
inputs和outputs在DefaultTask類中被定義為屬性或者有一個直接類來表示。對應的是TaskInputs和TaskOutputs。
為了便于表述,我們還是接著上一篇的那個例子,從配置文件version.properties中讀取參數,并打印出版本號:
version=new ProjectVersion(0,1)
class ProjectVersion{
Integer major
Integer minor
Boolean release
ProjectVersion(Integer major, Integer minor){
this.major=major
this.minor=minor
this.release=Boolean.FALSE
}
ProjectVersion(Integer major, Integer minor, Boolean release){
this.major=major
this.minor=minor
this.release=release
}
@Override
String toString(){
"$major.$minor${release?'': '-SNAPSHOT'}"
}
}
task printVersion << {
logger.quiet "Version: $version"
}
// Project接口提供了file方法,它會創建一個相對于項目目錄的java.io.File實例
ext.versionFile=file('version.properties')
task loadVersion{
project.version=readVersion()
}
//readVersion方法,與task是不同的
ProjectVersion readVersion(){
logger.quiet 'Reading the version file'
if(!versionFile.exists()){
throw new GradleException ("Required version file dose not exist:$versionFile.canonicalPath " )
}
//Groovy的文件實現通過添加新的方法來讀取InputStream
Properties versionProps=new Properties()
versionFile.withInputStream{stream->
versionProps.load(stream)
}
// 在Groovy中,如果return是方法中的最后一條語句的話,則可以將它省略
new ProjectVersion(versionProps.major.toInteger(),versionProps.minor.toInteger(),versionProps.release.toBoolean())
}
配置文件中的初始參數是這樣的:
major=0
minor=1
release=false
現在,我們要增加一個新的任務:新建一個名為makeReleaseVersion的task來將配置文件中的release屬性改為true。
task makeReleaseVersion(group :'versioning',description :'Makes project a release version.' )<< {
version.release=true
// Ant task 的propertyfile 提供了一種便利的方式來修改屬性文件
ant.propertyfile(file:versionFile){
entry(key:'release',type:'string',operation:'=',value: 'true')
}
}
執行gradle makeReleaseVersion
之后打開配置文件 version.properties 就可以看到文件中的release屬性已經變為true了。
執行 gradle printVersion
命令,可以看到結果
:printVersion
Version: 0.1
注意,雖然我們將配置文件中的release標記為true,但是Gradle并不知道。當我們再次執行makeReleaseVersion這個task的時候,doLast這個閉包中的代碼還是會執行,會花多余的時間。為了解決這個問題,需要聲明它的inputs和outputs。
task makeReleaseVersion(group :'versioning',description :'Makes project a release version.' ){
//在配置階段聲明inputs/outputs
//聲明版本的release屬性作為輸入
inputs.property('release',version.release)
//由于版本文件被修改了,所以它被聲明作為輸出文件屬性
outputs.file versionFile
doLast{
version.release=true
// Ant task 的propertyfile 提供了一種便利的方式來修改屬性文件
ant.propertyfile(file:versionFile){
entry(key:'release',type:'string',operation:'=',value: 'true')
}
}
}
記住:task的inputs和outputs屬性是在配置階段執行的用來連接task的依賴。這就是他們需要在配置塊中被定義的原因。為了避免出現所不期望出現的行為,請確保賦給inputs和outputs的值在配置階段是可訪問的。如果需要通過編程獲得輸出,可以通過TaskOutputs上的upToDateWhen(Closure)方法來實現。與常規的inputs和outputs相比,這個方法是在執行期間執行的。如果閉包返回true,這個task則會被認為是最新的。
如果執行兩次makeReleaseVersion任務,會發現Gradle已經知道配置文件中的release 已經變為true,會自動跳過第二次執行。
:makeReleaseVersion UP-TO-DATE
實際上,我們在apk打包過程中經??吹降腢P-TO-DATE 就是因為輸入輸出沒有發生變化,Gradle跳過了這個task的執行。
下一篇,我們開始學習Gradle中如何掛接到構建生命周期。