banner
jzman

jzman

Coding、思考、自觉。
github

Gradle系列之建構腳本基礎

本文將對 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 文件的使用,測試工程目錄如下:

├─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 文件內容如下:

println "---------test----Setting.gradle----------"
//輸出當前工程目錄
println(rootDir)
//指定要參與構建的子項目
include ':Method'
project(':Method').projectDir = new File(rootDir,'test/Method')

來看一下輸出結果:

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 中心庫下載,下面是參考代碼:

//配置子項目依賴的倉庫
subprojects{
	repositories{
		jcenter()
	}
}

//配置全部項目
allprojects{
	
}

...

通過本小節主要了解 build.gradle 文件的作用即可,實際開發中針對不同類型的項目會有更詳細的相應配置策略。

Project 和 Tasks#

在 Gradle 中有很多 Project,可將某個 Project 打包成 jar 提供給另一個 Project 使用,每個 Project 都是根據其業務需求抽象出來的一個子模塊,最終通過 Gradle 構建成完整的項目。

每個 Project 允許有多個 task,Task 理解為任務,task 主要 完成某個具體的功能點,比如 wrapper task 主要就是完成 wrapper 文件的創建。

任務的創建#

對於任務的創建已經比較熟悉了,下面使用 task 聲明一個任務:

//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,具體參考如下代碼:

//單任務依賴:通過dependsOn指定要依賴的任務
task B(dependsOn: A){
	doFirst{
		println 'B'
	}
}

task C{
	doFirst{
		println 'C'
	}
}

//多任務依賴
task D{
	dependsOn A, C
	doFirst{
		println 'D'
	}
}

下面看一下執行多依賴任務 gradle D 的執行結果:

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 的一個屬性,測試代碼如下:

//任務之間的交互
task E{
	println 'hello e'
	println "E是不是Project的屬性:"+project.hasProperty('E')
}

E.doFirst{
	println 'doFirst'
}

E.doLast{
	println 'doLast'
}

上述代碼的執行結果如下:

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 代碼塊,參考如下代碼定義自定義屬性:

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}"
	}
}

上述代碼的執行結果:

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 中可以利用相關語法來完成相關功能,下面是 Gradle 系列文章:

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。