- Gradle 之Groovy基本語(yǔ)法(一)
- Gradle 之Groovy文件操作(二)
- Gradle 之詳解Project(三)
- Gradle 之詳解Task(四)
- Gradle 之初識(shí)插件(五)
- Gradle 之常用配置(六)
- Gradle 之?dāng)U展Extension類 (七)
一赃梧、前言
Gradle在初始化階段會(huì)生成所有的Project對(duì)象,在配置階段會(huì)構(gòu)建Task有向無(wú)環(huán)圖新症,最后的執(zhí)行階段會(huì)執(zhí)行該Task和其相關(guān)的Task任務(wù)特咆。
這一章主要說(shuō)下毛俏,配置階段之前的Task的構(gòu)建和Task的執(zhí)行(沒(méi)有調(diào)用該Task也會(huì)讓配置階段執(zhí)行代碼執(zhí)行)宦赠。
二胸嘴、Task的定義
通過(guò)gradlew tasks可查看所有定義好的Task任務(wù)券犁。
Task定義方式:
1、Task task(String name,Closure configureClosure)
如:
task helloTask {
println 'hello world'
}
等價(jià)于:
task (helloTask,{
println 'hello world'
})
上面的調(diào)用:gradlew helloTask络断;強(qiáng)調(diào)一點(diǎn)的是該helloTask的執(zhí)行在配置階段中裁替。
2、TaskContainer getTasks() 通過(guò)容器
如:
this.getTasks().create(name:'helloTask') {
println 'hello world'
}
每個(gè)Project中會(huì)有個(gè)TaskContainer對(duì)象貌笨,該對(duì)象是為了管理該P(yáng)roject下的所有的Task弱判。
無(wú)論通過(guò)第一個(gè)方式還是第二個(gè)方式都會(huì)有個(gè)XXXXX(Map<String, ?> options, Closure configureClosure),第一個(gè)參數(shù)options是什么意思锥惋?
我們通過(guò)task(String name,Closure configureClosure)方式創(chuàng)建的時(shí)候昌腰,第一個(gè)String name實(shí)質(zhì)也可以理解成map的方式,也就是說(shuō)map可以保存很多的設(shè)置屬性膀跌。而且這些設(shè)置屬性都在Task的聲明中剥哑。
public interface Task extends Comparable<Task>, ExtensionAware {
String TASK_NAME = "name";
String TASK_DESCRIPTION = "description";
String TASK_GROUP = "group";
String TASK_TYPE = "type";
String TASK_DEPENDS_ON = "dependsOn";
String TASK_OVERWRITE = "overwrite";
String TASK_ACTION = "action";
}
- name : Task名稱
- description : Task描述
- group : Task屬于哪個(gè)組
- type : Task類型
- dependsOn : Task依賴于其他的Task
- overwrite :
- action:
Task中除了定義屬性外,還有對(duì)該屬性的操作方法淹父,我們可以在創(chuàng)建Task的時(shí)候就對(duì)添加屬性,也可以通過(guò)獲取特定的屬性通過(guò)setXXX方法設(shè)置怎虫。
二暑认、Task的執(zhí)行
前面也已經(jīng)介紹了Task的執(zhí)行方式是調(diào)用gradlew task名方式,上面的Task定義的是執(zhí)行在配置階段的大审,而且及時(shí)沒(méi)有明確的被調(diào)用該Task中的代碼還是會(huì)在配置階段執(zhí)行蘸际。
Task可以通過(guò)配置的方式,讓其執(zhí)行在配置階段還是執(zhí)行階段徒扶。
1粮彤、doFirst{} : 執(zhí)行階段
添加doFirst代碼是執(zhí)行階段執(zhí)行;不添加表示在配置階段執(zhí)行姜骡。
如:可以在Task中添加doFirst导坟,也可以通過(guò)找到Task添加doFirst。
this.getTasks().create(name: 'helloTask',description: 'hahahha') {
doFirst {
def name = 'hello'
println name
}
}
helloTask.doFirst {
println it.description
}
2圈澈、doLast{} : 執(zhí)行階段
在Task中通過(guò)添加doLast惫周,可以讓這部分代碼執(zhí)行在執(zhí)行階段
如:創(chuàng)建一個(gè)helloTask任務(wù),通過(guò)執(zhí)行該任務(wù)康栈,他的打印結(jié)果為:“world”递递,因?yàn)榕渲秒A段的先執(zhí)行喷橙,最后再順序執(zhí)行執(zhí)行階段內(nèi)容。
this.getTasks().create(name: 'helloTask',description: 'hahahha') {
def name = 'hello'
doLast {
println name
}
name = 'world'
}
3登舞、<< : 執(zhí)行階段
當(dāng)Task中的代碼都執(zhí)行在執(zhí)行階段的時(shí)候贰逾,用<<來(lái)簡(jiǎn)寫(xiě)代替doLast
this.getTasks().create(name: 'helloTask',description: 'hahahha') << {
def name = 'hello'
println name
}
例子:計(jì)算執(zhí)行執(zhí)行階段到執(zhí)行階段結(jié)束時(shí)間
this.afterEvaluate { Project project->
def startBuildTime,endBuildTime
def preBuildTask = project.tasks.getByName('preBuild')
def buildTask = project.tasks.getByName('build')
preBuildTask.doFirst {
startBuildTime = System.currentTimeMillis()
println "preBuildTask time is ${startBuildTime}"
}
buildTask.doLast {
endBuildTime = System.currentTimeMillis()
println "preBuildTask time is ${endBuildTime}"
println "執(zhí)行時(shí)間為: ${endBuildTime-startBuildTime}"
}
}
二、Task的執(zhí)行順序
Task的執(zhí)行順序:
- 1菠秒、dependOn方式設(shè)置
- 2疙剑、輸入輸出方式
- 3、通過(guò)API指定順序
1)稽煤、dependOn方式
如:
task taskZ << {
println 'taskZ'
}
task taskX(dependsOn: taskZ) << {
println 'taskX'
}
task taskY(dependsOn: [taskX,taskZ]) << {
println 'taskY'
}
定義了taskX核芽、taskY和taskZ三個(gè)Task,并指定taskY依賴于taskX酵熙,而taskX依賴于taskZ轧简;當(dāng)執(zhí)行taskY的時(shí)候他們的輸出順序如下:
taskZ
taskX
taskY
2)、輸入輸出方式
當(dāng)一個(gè)參數(shù)作為TaskA的輸出參數(shù)匾二,卻作為TaskB的輸入?yún)?shù)哮独。那么當(dāng)執(zhí)行TaskB的時(shí)候先要執(zhí)行TaskA。即輸出的Task先于輸入的Task執(zhí)行察藐。
輸入方式:
- TaskInputs property(String name, Object value);
- TaskInputs properties(Map<String, ?> properties);
通過(guò)輸入一些鍵值對(duì)的方式皮璧,KEY為String類型,value為任意類型分飞。
輸出方式:
- TaskOutputFilePropertyBuilder dirs(Object... paths);
- TaskOutputFilePropertyBuilder file(Object path);
- TaskOutputFilePropertyBuilder dir(Object path);
3)悴务、指定順序方式mustRunAfter
如:
task taskX << {
doLast {
println 'taskX'
}
}
task taskY {
mustRunAfter(taskX)
doLast {
println 'taskY'
}
}
task taskZ << {
mustRunAfter(taskY)
doLast {
println 'taskZ'
}
}
三、Gradle生命周期內(nèi)執(zhí)行Task
怎么樣通過(guò)代碼調(diào)用Task
this.afterEvaluate {
def buildTask = it.tasks.findByName('build')
if (buildTask != null) {
buildTask.doLast {
taskZ.execute()
}
}
}
在buildTask執(zhí)行中添加對(duì)taskZ的執(zhí)行譬猫。