作為一個(gè)構(gòu)建腳本的開發(fā)者,你不應(yīng)該局限于編寫任務(wù)動(dòng)作或者配置邏輯,有時(shí)候你想在指定的生命周期事件發(fā)生的時(shí)候執(zhí)行一段代碼。生命周期事件可以在指定的生命周期之前、之中或者之后發(fā)生,在執(zhí)行階段之后發(fā)生的生命周期事件就該是構(gòu)建的完成了。
假設(shè)你希望在構(gòu)建失敗時(shí)能夠在開發(fā)階段盡早得到反饋,給構(gòu)建生命周期事件添加回調(diào)有兩種方法:一是通過閉包,二是實(shí)現(xiàn)Gradle API的一個(gè)監(jiān)聽接口,Gradle并沒有要求你監(jiān)聽生命周期事件,這完全決定于你,通過監(jiān)聽器實(shí)現(xiàn)的優(yōu)勢(shì)就是可以給你的類寫單元測(cè)試,看看下面這幅圖會(huì)有一點(diǎn)直觀的印象:
http://wiki.jikexueyuan.com/project/gradleIn-action/images/dag27.png" alt="" />
在配置階段,Gradle決定在任務(wù)在執(zhí)行階段的執(zhí)行順序,依賴關(guān)系的內(nèi)部結(jié)構(gòu)是通過直接的無環(huán)圖(DAG)來表示的,圖中的每一個(gè)任務(wù)稱為一個(gè)節(jié)點(diǎn),每一個(gè)節(jié)點(diǎn)通過邊來連接,你很有可能通過dependsOn或者隱式的依賴推導(dǎo)來創(chuàng)建依賴關(guān)系。記住DAG圖從來不會(huì)有環(huán),就是說一個(gè)已經(jīng)執(zhí)行的任務(wù)不會(huì)再次執(zhí)行,下面這幅圖將要的展示了這個(gè)過程:
http://wiki.jikexueyuan.com/project/gradleIn-action/images/dag28.png" alt="" />
回想一下之前我們實(shí)現(xiàn)的makeReleaseVersion任務(wù)是在release任務(wù)之前執(zhí)行的,我們可以編寫一個(gè)生命周期回調(diào)方法來取代之前寫一個(gè)任務(wù)來執(zhí)行版本修改任務(wù)。構(gòu)建系統(tǒng)準(zhǔn)確知道在執(zhí)行之前應(yīng)該運(yùn)行哪些任務(wù),你可以查詢?nèi)蝿?wù)圖來查看它是否存在,下面這幅圖展示了訪問任務(wù)執(zhí)行圖的相關(guān)接口:
http://wiki.jikexueyuan.com/project/gradleIn-action/images/dag29.png" alt="" />
接下來我們來添加相應(yīng)的監(jiān)聽方法,下面這段代碼通過調(diào)用whenReady方法來注冊(cè)回調(diào)接口,當(dāng)任務(wù)圖創(chuàng)建的時(shí)候這個(gè)回調(diào)會(huì)自動(dòng)執(zhí)行,你知道這個(gè)邏輯會(huì)在任何任務(wù)之前執(zhí)行,所以你可以移除makeReleaseVersion任務(wù)。
gradle.taskGraph.whenReady { TaskExecutionGraph taskGraph ->
//檢查任務(wù)圖是否包括release任務(wù)
if(taskGraph.hasTask(release)) {
if(!version.release) {
version.release = true
ant.propertyfile(file: versionFile) {
entry(key: 'release', type: 'string', operation: '=',
value: 'true')
}
}
}
}
你也可以實(shí)現(xiàn)一個(gè)監(jiān)聽器來實(shí)現(xiàn)同樣的效果,首先在構(gòu)建腳本中編寫一個(gè)實(shí)現(xiàn)指定監(jiān)聽器的類,然后在構(gòu)建中注冊(cè)這個(gè)實(shí)現(xiàn),監(jiān)聽任務(wù)執(zhí)行圖的接口是TaskExecutionGraphListener,編寫的時(shí)候你只需要實(shí)現(xiàn)graphPopulate(TaskExecutionGraph)方法,下圖表示了這個(gè)過程:
http://wiki.jikexueyuan.com/project/gradleIn-action/images/dag30.png" alt="" />
下面是編程實(shí)現(xiàn):
class ReleaseVersionListener implements TaskExecutionGraphListener {
final static String releaseTaskPath = ':release'
@Override
void graphPopulated(TaskExecutionGraph taskGraph) {
//查看是否包含release任務(wù)
if(taskGraph.hasTask(releaseTaskPath)) {
List<Task> allTasks = taskGraph.allTasks
//查找release任務(wù)
Task releaseTask = allTasks.find {it.path == releaseTaskPath }
Project project = releaseTask.project
if(!project.version.release) {
project.version.release = true
project.ant.propertyfile(file: project.versionFile) {
entry(key: 'release', type: 'string', operation: '=',
? value: 'true')
}
}
}
}
}
def releaseVersionListener = new ReleaseVersionListener()
//注冊(cè)監(jiān)聽器
gradle.taskGraph.addTaskExecutionGraphListener(releaseVersionListener)