1. 程式人生 > >Gradle系列之構建指令碼基礎

Gradle系列之構建指令碼基礎

> 原文發於微信公眾號 jzman-blog,歡迎關注交流。 前面兩篇文章分別介紹了 Gradle 基礎知識以及 Groovy 相關基礎知識,這也是學習 Gradle 所必需瞭解的,文章連結如下:: - [Gradle系列之初識Gradle](https://juejin.im/post/5d1240bfe51d454f6f16ec1b) - [Gradle之Groovy基礎篇](https://juejin.im/post/5d14efc2e51d4510835e02d7) 本文將對 Gradle 整體進行了介紹和學習,瞭解了 Task、Project 等相關概念以及對使用 Gradle 來構建專案的一些常用操作,主要內容如下: 1. Setting 檔案 2. Build 檔案 3. Project 和 Tasks 4. 任務的建立 5. 任務依賴 6. 任務間的互動 7. 自定義屬性 8. 總結 #### Setting 檔案 說一下 Gradle 構建專案的 Setting 檔案,該檔案主要用來配置當前工程,比如 Android 開發中一個專案中可能有多個子 Module,當不需要某個子 Module 時,可以取消該 Module 在配置檔案 Setting 中的配置即可,當然只有在 Setting 檔案中配置的子 Module 才會被構建,當然不只是 Android 開發,只要使用 Gradle 構建的專案都一樣,Setting 是 Gradle 構建專案預設的配置檔名,下面簡單測試一下 Setting.gradle 檔案的使用,測試工程目錄如下: ```java ├─GradleSetting │ ├─.gradle │ │ ├─4.1 │ │ │ ├─fileChanges │ │ │ ├─fileHashes │ │ │ └─taskHistory │ │ └─buildOutputCleanup │ └─test │ └─Method │ └─.gradle │ ├─4.1 │ │ ├─fileChanges │ │ ├─fileHashes │ │ └─taskHistory │ └─buildOutputCleanup │ build.gradle │ setting.gradle ``` 在工程名為 GradleSetting 的工程中 test 資料夾下有一個 Method 的子專案,這裡會通過配置 setting.gradle 檔案將子專案 Method 構建到 GradleSetting 中,setting.gradle 檔案內容如下: ```java println "---------test----Setting.gradle----------" //輸出當前工程目錄 println(rootDir) //指定要參與構建的子專案 include ':Method' project(':Method').projectDir = new File(rootDir,'test/Method') ``` 來看一下輸出結果: ```java PS E:\Gradle\study\GradleSetting> gradle testGradleSetting ---------test----Setting.gradle---------- E:\Gradle\study\GradleSetting > Configure project : testGradleSetting > Configure project :Method 3 3 30 獲取方法返回的結果:30 1 2 3 4 5 BUILD SUCCESSFUL in 2s ``` 因為在 setting.gradle 檔案中配置了 Method,從輸出結果看 Method 確實參與了構建,取消在 setting.gradle 檔案中的配置,則不會構建 Method,最好自己驗證一下。 上面配置了子專案 Method 所在的位置,如果不指定則預設是與 setting.gradle 同級的目錄。 #### Build 檔案 如果選擇使用 Gradle 構建專案,則每個專案都有一個 build.gradle 檔案,該檔案是專案構建的入口,對整個專案的配置生效,可以在根專案配置子專案的一下通用配置,比如配置子專案的倉庫為 jcenter,這樣子專案中所有的依賴就指向 jcenter 中心庫下載,下面是參考程式碼: ```java //配置子專案依賴的倉庫 subprojects{ repositories{ jcenter() } } //配置全部專案 allprojects{ } ... ``` 通過本小節主要了解 build.gradle 檔案的作用即可,實際開發中針對不同型別的專案會有更詳細的相應配置策略。 #### Project 和 Tasks 在 Gradle 中有很多 Project,可將某個 Project 打包成 jar 提供給另一個 Project 使用,每個 Project 都是根據其業務需求抽象出來的一個子模組,最終通過 Gradle 構建成完整的專案。 每個 Project 允許有多個 task,Task 理解為任務,task 主要 完成某個具體的功能點,比如 wrapper task 主要就是完成 wrapper 檔案的建立。 #### 任務的建立 對於任務的建立已經比較熟悉了,下面使用 task 宣告一個任務: ```java //1. 建立一個任務 task createTask{ doFirst{ println 'doFirst' } doLast{ println 'doLast' } } //2. 使用TaskContainer建立一個任務,Project已經定義的TaskContainer,即tasks tasks.create("createTask1"){ doFirst{ println 'doFirst' } doLast{ println 'doLast' } } ``` task 可以理解為建立任務的關鍵字,實際上 task 是 Project 裡面的一個方法,在 Groovy 中可以省略方法引數上的括號,花括號裡的內容是一個閉包,主要是對 task 進行相關配置,doFirst 和 doLast 是 Task 中常用的兩個方法,分別會在該 task 開始和結束時執行。 #### 任務依賴 任務之間可以相互依賴,可以控制某個任務執行的先後順序,比如在執行 A 之前必須先執行 B,此時任務 A 依賴任務 B,具體參考如下程式碼: ```java //單任務依賴:通過dependsOn指定要依賴的任務 task B(dependsOn: A){ doFirst{ println 'B' } } task C{ doFirst{ println 'C' } } //多工依賴 task D{ dependsOn A, C doFirst{ println 'D' } } ``` 下面看一下執行多依賴任務 gradle D 的執行結果: ```java PS E:\Gradle\study\GradleSetting> gradle D > Task :A A > Task :C C > Task :D D BUILD SUCCESSFUL in 2s ``` 顯然,執行任務 D,其依賴的其他兩個任務先執行,控制了任務執行的先後順序。 **注意**:指令碼是按照順序執行,如果任務任務 A 和 C 在任務 D 的後面定義,當執行任務 D 的時候肯定會出錯。 #### 任務間的互動 建立的任務都有自己的名稱,其型別是 Task,那麼我們就可以通過 Task API 來控制控制任務的執行,使用任務名操作任務的原理是:Project 在建立任務的時候,已經將該任務對應的任務宣告為 Project 物件的一個型別為 Task 的一個屬性,測試程式碼如下: ```java //任務之間的互動 task E{ println 'hello e' println "E是不是Project的屬性:"+project.hasProperty('E') } E.doFirst{ println 'doFirst' } E.doLast{ println 'doLast' } ``` 上述程式碼的執行結果如下: ```java PS E:\Gradle\study\GradleSetting> gradle E > Configure project : hello e E是不是Project的屬性:true > Task :E doFirst doLast BUILD SUCCESSFUL in 1s ``` #### 自定義屬性 Project 和 Task 都允許使用者新增額外的自定義屬性,通過應用所屬對應的 ext 屬性來實現,新增之後可以通過 ext 屬性對自定義的屬性進行讀取和設定,如果要同時新增多個自定義屬性,可以通過 ext 程式碼塊,參考如下程式碼定義自定義屬性: ```java apply plugin:"java" //自定義單個屬性 ext.name1 = "Gradle" //自定義多個屬性 ext{ age = 10 score = 100 } //在SourceSet中使用自定義屬性 sourceSets.all{ ext.resourceDir = null } //配置自定義屬性 sourceSets{ main{ resourceDir = "main/res" } test{ resourceDir = "test/res" } } task customProperty{ println "name=${name1}" println "age=${age}" println "score=${score}" sourceSets.each { println "${it.name} resourceDir is ${it.resourceDir}" } } ``` 上述程式碼的執行結果: ```java PS E:\Gradle\study\GradleSetting> gradle customProperty > Configure project : name=Gradle age=10 score=100 main resourceDir is main/res test resourceDir is test/res BUILD SUCCESSFUL in 2s ``` 自定義屬性相較區域性變數作用域更加廣泛,可以跨 Task、Project 訪問自定義屬性,只要能訪問這些屬性所屬的物件,那麼這些屬性就可以被訪問到, Android 開發中可以使用自定義屬性單獨定義版本號、版本名稱以及用到的第三方庫的版本,將其同意在單獨的 gradle 檔案中,各 Module 直接獲取即可,不僅方便管理依賴庫的版本,還在一定程度上提高工作效率。 #### 總結 Gradle 指令碼基於 Grooy ,而 Groovy 完全相容 Java 語法,Gradle 指令碼本質上還是程式碼,在 Gradle 中可以利用相關語法來完成相關功能。可以關注公眾號:躬行之(jzman-blog),一起交流學習。 ![](https://img2020.cnblogs.com/blog/758808/202007/758808-20200713234422479-21365709