博客主頁html
學完了Groovy核心語法後,接下來學習Gradle。java
Gradle是一款構建系統工具,它的DSL基於Groovy實現,大部分功能都是經過插件的方法實現的,若是內置插件不能知足需求,能夠自定義本身的插件。segmentfault
咱們能夠參考文檔學習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
Wrapper,其實就是對Gradle的一層包裝,以便開發中統一Gradle的構建版本,避免版本的不統一。
當使用Wrapper啓動Gradle時,Wrapper會檢查Gradle有沒有被下載關聯,沒有就會從配置的地址下載並運行構建,不須要配置Gradle環境了。ide
咱們能夠執行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
學習
在build.gradle構建文件中自定義Wrapper Task
task wrapper(type: Wrapper) { gradleVersion = '5.1' } > gradlew wrapper
執行完task後,就會生成5.1版本的Wrapper,就不須要手動指定Gradle版本。
Gradle日誌級別增長了QUIET和LIFECYCLE兩個級別。Gradle日誌級別以下:
ERROR 錯誤消息
QUIET重要消息
WARNING警告消息
LIFECYCLE進度消息
INFO信息消息
DEBUG調試消息
// -q 或者 --quite 輸出QUIET級別及其之上的日誌信息 > gradlew -q tasks // -i 或者 --info 輸出INFO級別及其之上的日誌信息 > gradlew -i tasks // 不加選項,輸出LIFECYCLE級別及其更高級別 // -d 或者 --debug 輸出DEBUG級別及其更高級別,這個會輸出全部日誌
默認狀況下,堆棧信息的輸出是關閉的,能夠經過命令行增長參數的形式打開它,在構建失敗時,Gradle就會輸出錯誤堆棧信息
// 推薦使用-s,由於-S輸出的堆棧信息太多 > gradlew -s tasks // -s 或者 --stacktrace 輸出關鍵的堆棧信息 // -S 或者 --full-stacktrace 輸出所有堆棧信息
通常狀況下,咱們都是使用print系列的方法輸出日誌,它的級別爲QUIET
println '輸出的日誌信息'
還可使用內置的logger輸出不一樣級別的日誌信息:
logger.quiet('quiet日誌') logger.lifecycle("lifecycle日誌")
其實內部實現就是調用Project的getLogger()方法獲取Logger對象的實例。
通常查看幫助文檔,只需在命令後加上-h 或者 --help,有的是-?
> gradlew -? > gradlew -h > gradlew --help
執行下面命令後,會列出全部可執行的task
> gradlew tasks
主要爲了解決緩存引起的問題,經過下面命令從新下載依賴,不會走緩存
> gradlew --refresh-dependencies assemble
經過命令執行多個任務,只須要按順序以空格隔開便可,好比下面命令,先是執行clean進行文件清理,再執行打包命令
> gradlew clean assembleArmDebug
https://docs.gradle.org/3.3/u...
Gradle構建過程一般分爲三步
Gradle支持單個和多個工程的編譯。在初始化階段,Gradle判斷須要參與編譯的工程,爲每一個工程建立一個Project對象。
在這個階段,Gradle會建立Settings對象,並在其上執行settings.gradle
腳本,創建工程之間的層次關係。
在這個階段,Gradle會分別在每一個Project對象上執行對應的build.gradle
腳本,對Project進行配置。
在執行階段,Gradle會判斷配置階段建立的哪些Task須要被執行,而後執行選中的每一個Task。
在Gradle中能夠監聽各階段:
在settings.gradle文件中
println "初始化階段開始..."
在build.gradle文件中添加監聽回調
this.afterEvaluate { println "配置階段完成以後的監聽回調" } this.gradle.buildFinished { println "gradle執行完畢後的監聽回調" }
在Gradle中,settings文件主要用於初始化以及工程樹的配置,默認名爲settings.gradle,存放在項目根目錄下。
根工程至關於Android Studio中的Project,一個根工程能夠有多個子工程,也就是多個Module。
一個子工程只有在settings.gradle文件中配置了,Gradle才能識別,也就是在構建時在包含進入。
include ':app', ':basiclib'
每一個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配置。
一個Project能夠由多個Task組成。其實Task就是一個原子性操做,好比:打個jar包,複製一份文件,上次jar到Maven中心倉庫等。
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.
從上面腳本中可知,能夠調用 doFirst 和 doLast 方法,在任務執行先後作一些操做。使用任務名操做任務的原理是: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
若是個人文章對您有幫助,不妨點個贊鼓勵一下(^_^)