Gradle核心(一):Gradle入門、生命週期探索、基本腳本構建

博客主頁html

學完了Groovy核心語法後,接下來學習Gradle。java

Gradle是一款構建系統工具,它的DSL基於Groovy實現,大部分功能都是經過插件的方法實現的,若是內置插件不能知足需求,能夠自定義本身的插件。segmentfault

Gradle入門及生命週期探索

咱們能夠參考文檔學習Gradle入門。
這裏Gradle怎麼下載,怎麼安裝就不說了,能夠自行百度學習。
安裝完成後,能夠經過下面命令校驗gradle版本緩存

// Window os
gradlew -v

// Linux os
./gradle -v

如今來編寫第一個Gradle腳本閉包

// build.gradle
task hello {
    doLast {
       println "Hello World!"
    }
}

// 執行build.gradle腳本中定義的hello任務
// -q 參數用於控制gradle輸出的日誌級別,以及哪些日誌能夠輸出被看見
> gradlew -q hello
// 控制檯輸出信息
Hello World!

build.gradle是Gradle默認的構建腳本文件。定義一個任務(Task),任務的名字爲hello,並給任務hello添加一個動做(Action),其實就是Groovy語言實現的閉包。doLast 是Task執行完畢後要回調執行的代碼。app

Gradle Wrapper

Wrapper,其實就是對Gradle的一層包裝,以便開發中統一Gradle的構建版本,避免版本的不統一。
當使用Wrapper啓動Gradle時,Wrapper會檢查Gradle有沒有被下載關聯,沒有就會從配置的地址下載並運行構建,不須要配置Gradle環境了。ide

生成Wrapper

咱們能夠執行Gradle內置的task自動生成Wrapper函數

> gradlew wrapper

// 將會生成下圖的Wrapper配置,gradlew,gradlew.bat文件
// gradlew和gradlew.bat分別是Linux和Windows下的可執行腳本文件,與Gradle原生命令用法同樣

在執行gradlew wrapper命令時,也能夠指定參數,如:Gradle版本,Gradle下載地址等工具

// 指定Gradle版本,不指定就默認當前安裝的Gradle版本
> gradlew wrapper --gradle-version 4.1

該參數影響的是gradle-wrapper.properties配置中的distributionUrl的值,該值的規則:distributionUrl=https\://services.gradle.org/distributions/gradle-${gradle-version}-all.zip學習

自定義Wrapper Task

build.gradle構建文件中自定義Wrapper Task

task wrapper(type: Wrapper) {
    gradleVersion = '5.1'
}

> gradlew wrapper

執行完task後,就會生成5.1版本的Wrapper,就不須要手動指定Gradle版本。

Gradle日誌

日誌級別

Gradle日誌級別增長了QUIETLIFECYCLE兩個級別。Gradle日誌級別以下:
ERROR 錯誤消息
QUIET重要消息
WARNING警告消息
LIFECYCLE進度消息
INFO信息消息
DEBUG調試消息

// -q 或者 --quite 輸出QUIET級別及其之上的日誌信息
> gradlew -q tasks

// -i 或者 --info 輸出INFO級別及其之上的日誌信息
> gradlew -i tasks

// 不加選項,輸出LIFECYCLE級別及其更高級別
// -d 或者 --debug 輸出DEBUG級別及其更高級別,這個會輸出全部日誌

輸出Gradle錯誤堆棧信息

默認狀況下,堆棧信息的輸出是關閉的,能夠經過命令行增長參數的形式打開它,在構建失敗時,Gradle就會輸出錯誤堆棧信息

// 推薦使用-s,由於-S輸出的堆棧信息太多
> gradlew -s tasks

// -s 或者 --stacktrace  輸出關鍵的堆棧信息
// -S 或者 --full-stacktrace 輸出所有堆棧信息

腳本中添加日誌輸出

通常狀況下,咱們都是使用print系列的方法輸出日誌,它的級別爲QUIET

println '輸出的日誌信息'

還可使用內置的logger輸出不一樣級別的日誌信息:

logger.quiet('quiet日誌')
logger.lifecycle("lifecycle日誌")

其實內部實現就是調用ProjectgetLogger()方法獲取Logger對象的實例。

Gradle命令行

查看幫助文檔命令

通常查看幫助文檔,只需在命令後加上-h 或者 --help,有的是-?

> gradlew -?
> gradlew -h
> gradlew --help

查看全部可執行的Tasks

執行下面命令後,會列出全部可執行的task

> gradlew tasks

強制刷新依賴

主要爲了解決緩存引起的問題,經過下面命令從新下載依賴,不會走緩存

> gradlew --refresh-dependencies assemble

多任務調用方式

經過命令執行多個任務,只須要按順序以空格隔開便可,好比下面命令,先是執行clean進行文件清理,再執行打包命令

> gradlew clean assembleArmDebug

Gradle生命週期探索

https://docs.gradle.org/3.3/u...

Gradle構建過程一般分爲三步

初始化階段 Initialization

Gradle支持單個和多個工程的編譯。在初始化階段,Gradle判斷須要參與編譯的工程,爲每一個工程建立一個Project對象。

在這個階段,Gradle會建立Settings對象,並在其上執行settings.gradle腳本,創建工程之間的層次關係。

配置階段 Configuration

在這個階段,Gradle會分別在每一個Project對象上執行對應的build.gradle腳本,對Project進行配置。

執行階段 Execution

在執行階段,Gradle會判斷配置階段建立的哪些Task須要被執行,而後執行選中的每一個Task。

在Gradle中能夠監聽各階段:
在settings.gradle文件中

println "初始化階段開始..."

在build.gradle文件中添加監聽回調

this.afterEvaluate {
    println "配置階段完成以後的監聽回調"
}

this.gradle.buildFinished {
    println "gradle執行完畢後的監聽回調"
}

Gradle構建腳本基礎探索

settings文件

在Gradle中,settings文件主要用於初始化以及工程樹的配置,默認名爲settings.gradle,存放在項目根目錄下。

根工程至關於Android Studio中的Project,一個根工程能夠有多個子工程,也就是多個Module。
一個子工程只有在settings.gradle文件中配置了,Gradle才能識別,也就是在構建時在包含進入。

include ':app', ':basiclib'

build文件

每一個Project都會有一個Build文件,該文件是該Project構建入口。能夠配置版本,插件,依賴庫等。

Root Project也有一個Build文件,在該文件中能夠獲取全部的Child Project,因此咱們能夠對Child Project統一配置,如插件,依賴Maven倉庫等,這樣就不用對每一個Project去配置。若是配置全部的Child Project倉庫爲jcenter,能夠以下配置:

subprojects {
    repositories {
       println "subprojects>> name: ${project.getName()}"
       jcenter()
    }
}

除了subprojects外,還提供了allprojects,這個是對全部的Project配置。

Projects 、Tasks

一個Project能夠由多個Task組成。其實Task就是一個原子性操做,好比:打個jar包,複製一份文件,上次jar到Maven中心倉庫等。

建立一個task

task customTask {
    doFirst {
        println "custom task>>> doFirst"
    }

    doLast {
        println "custom task>>> doLast"
    }
}

// 執行任務, -s 輸出錯誤堆棧信息
> gradlew -s customTask

task 實際上是Project對象的一個函數,customTask 爲任務的名字。原型:Task task(String name, Closure configureClosure),Groovy語法中,最後一個參數是閉包時,能夠放在括號的外面,而方法的括號能夠省略。

還能夠經過TaskContainer建立任務,Project對象已經定義好了一個TaskContainer

tasks.create("customTask") {
    doFirst {
        println "TaskContainer custom task>>> doFirst"
    }

    doLast {
        println "TaskContainer custom task>>> doLast"
    }
}

// 執行任務, -s 輸出錯誤堆棧信息
> gradlew -s customTask

任務依賴

任務之間能夠有依賴關係,也就是說一個任務執行完後,才能執行其餘任務。能夠經過dependsOn指定其依賴的任務。

task customTask1 {
    doLast {
        println "customTask1 running."
    }
}

// customTask2的執行會依賴於customTask1
task customTask2(dependsOn: customTask1) {
    doLast {
        println "customTask2 running."
    }
}

> gradlew  customTask2

// 輸出打印信息,customTask1 會優先 customTask2 執行
customTask1 running.
customTask2 running.

一個任務也能夠同時依賴多個任務,dependsOn是Task類的一個方法,能夠接受多個依賴的任務做爲參數

task customTask1 {
    doLast {
        println "customTask1 running."
    }
}

task customTask2 {
    doLast {
        println "customTask2 running."
    }
}

task customTask3 {
    // customTask3 的執行,依賴於customTask1 , customTask12
    // 多個任務,用逗號隔開,在前面的任務會先執行,如:customTask1任務
    dependsOn customTask1, customTask2
    doLast {
        println "customTask3 running."
    }
}

// 執行customTask3任務
> gradlew customTask3

// 輸出打印信息,
:customTask1
customTask1 running.

:customTask2
customTask2 running.

:customTask3
customTask3 running.

經過任務名操做任務

能夠經過任務名(任務類型是Task),使用Task的API訪問它的方法、屬性、或者對任務從新配置。

task customTask1 {
    println "customTask1 running."
}

customTask1.doFirst {
    println "customTask1 doFirst running."
}

customTask1.doLast {
    println "has customTask1 property ${project.hasProperty('customTask1')}"
    println "customTask1 doLast running."
}

// 執行任務
> gradlew customTask1

// 輸出打印信息
customTask1 running.
customTask1 doFirst running.
has customTask1 property true
customTask1 doLast running.

從上面腳本中可知,能夠調用 doFirstdoLast 方法,在任務執行先後作一些操做。使用任務名操做任務的原理是:Project在建立該任務的時候,同時把該任務對用的任務名註冊爲Project的一個屬性,類型爲Task。經過project.hasProperty(String propertyName)能夠檢查是否有這個屬性。

自定義屬性

Project和Task均可以添加額外的自定義屬性,經過應用所屬對應的ext屬性實現。若是自定義多個屬性,使用代碼塊。能夠跨Project,跨Task訪問自定義屬性。

// 自定義有個Project屬性
ext.myName = 'kerwin'

// 自定義多個屬性經過代碼塊
ext {
    myAge = 12
    myPhone = 13564954189
}

task customTask {
    doLast {
        println "myName: ${myName}"
        println "myAge: ${myAge}"
        println "myPhone: ${myPhone}"
    }
}
// 執行任務
> gradlew customTask 
// 輸出結果
myName: kerwin
myAge: 12
myPhone: 13564954189

若是個人文章對您有幫助,不妨點個贊鼓勵一下(^_^)

相關文章
相關標籤/搜索