Gradle學習5——Gradle增量式構建

學習本系列前可以下載相關的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。

TaskInputs和TaskOutputs.png

為了便于表述,我們還是接著上一篇的那個例子,從配置文件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中如何掛接到構建生命周期。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容