Gradle技術之四 - Gradle的Task詳解
1 Gradle的Task詳解
- 1 Task定義和配置
- 2 Task的執行
- 3 Task的依賴和執行順序
- 4 Task型別
- 5 Task結合gradle的生命週期
- 6 Task實戰
1.1 Task定義和配置
1.1.1 檢視所有的task
./gradlew tasks 輸出 > Task :tasks ------------------------------------------------------------ All tasks runnable from root project ------------------------------------------------------------ Android tasks ------------- androidDependencies - Displays the Android dependencies of the project. signingReport - Displays the signing info for each variant. sourceSets - Prints out all the source sets defined in this project. Build tasks ----------- assemble - Assembles all variants of all applications and secondary packages. .....
1.1.1 新建一個task
可以使用project的task()方法建立一個task,也可以使用project的TaskContainer去建立task,這兩種方法建立的task沒有任何區別,TaskContainer就是方便project管理task用的,通過TaskContainer可以對project下的task進行管理,比如建立,查詢task等
//第一種方法,直接使用project的task()方法建立 task helloTask{ println 'this is helloTask' } //第二種方法,使用TaskContainer建立task this.tasks.create(name:'helloTask2'){ println 'this is helloTask2' }
1.1.2 對task進行配置
有兩種方法可以對task進行配置
1 建立的時候就對task進行配置
2 在閉包中對task進行配置
//第一種方法,直接使用project的task()方法建立 //第一種配置方法,建立的時候就配置task的group和description //description就是個說明,類似對註釋 task helloTask(group:'hard',description:'task learn'){ println 'this is helloTask' } //第二種方法,使用TaskContainer建立task this.tasks.create(name:'helloTask2'){ //第二種配置方式:直接在閉包中配置 setGroup('hard') setDescription('task learn') println 'this is helloTask2' }
通過配置以後,就可以在右側的面板中看到task了,如下圖:
1.1.3 task的執行順序
//第一種方法,直接使用project的task()方法建立
//配置的時候就配置task的group和description
//description就是個說明,類似對註釋
task helloTask(group:'hard',description:'task learn'){
//直接寫在閉包裡面的,是在配置階段就執行的
println 'this is helloTask'
doFirst {
println 'task in do first' //執行任務時,會第一個執行
}
doLast {
println 'task in do last' //執行任務時,會最後一個執行
}
}
doFirst和doLast中的程式碼,不執行這個任務時,是不會執行的,但是直接寫在閉包中的,就也是在這兩個函式外的程式碼,是在配置階段就會執行的。執行任務時,doFirst中的程式碼最先執行,doLast中的程式碼最後執行
切記大部分的內容是寫在 doLast{} 或 doFirst{} 閉包中,因為寫在如果寫在 task 閉包中的話,會在 Configuration 階段也被執行。
1.1.4 計算build編譯時間
def startBuildTime
def endBuildTime
//配置完後,所有的task的拓撲圖都已經生成好了
//保證要找的task已經配置完畢
this.afterEvaluate { Project project ->
//找到第一個執行的task
def preBuildTask = project.tasks.getByName('preBuild')
preBuildTask.doFirst {
startBuildTime = System.currentTimeMillis()
println 'the start time is:' + startBuildTime
}
//找到最後一個編譯的build任務
def buildTask = project.tasks.getByName('build')
buildTask.doLast {
endBuildTime = System.currentTimeMillis()
println 'the build time is:' + (endBuildTime - startBuildTime)
}
}
1.1.5 task依賴
task之間是有依賴關係的,比如taskA 依賴 taskB,那麼在執行taskA的時候,Gradle會先執行taskB,再執行taskA,我們可以在定義一個task的時候,指定task的依賴關係:
task taskB {
doLast {
println '我是taskB'
}
}
//定義一個taskA,且依賴於taskB
task taskA(dependsOn: taskB) {
doLast {
println '我是taskA'
}
}
//執行
./gradlew taskA
輸出
> Task :app:taskB
我是taskB
> Task :app:taskA
我是taskA
或者定義taskA,taskB之後,再定義依賴關係:
task taskB {
doLast {
println '我是taskB'
}
}
//定義一個taskA
task taskA() {
doLast {
println '我是taskA'
}
}
//定義之後,再依賴於taskB
taskA.dependsOn taskB
//執行
./gradlew taskA
輸出
> Task :app:taskB
我是taskB
> Task :app:taskA
我是taskA
一個task也可以依賴多個task,依賴多個task的話,直接在denpendsOn後面跟一個task列表:
taskA.dependsOn 'taskB','taskC'
或者在定義的時候
task taskA(dependsOn:['taskB','taskC']) {
doLast {
println '我是taskA'
}
}
執行taskA的時候,先執行taskB,taskC,但是taskB,taskC的執行順序是隨機的。
1.1.6 將自定義的task掛到構建過程中去
比如有這樣一個需求,我們需要在build之後,就執行我們的task,應該怎麼寫呢?
這就是把我們自定義的task掛到build後,程式碼如下:
afterEvaluate{ project ->
def buildTask = project.tasks.findByName('build')
if(buildTask == null){
throw new GradleException('the build task is not found')
}
//在buildTask後新增doLast,並在裡面執行printTask
//這樣我們就把自定義的task掛到build構建過程中了
buildTask.doLast {
printTask.execute()
}
}
SourceSets類的作用
SourceSets類的作用就是定義去哪找原始檔,去哪找資原始檔,庫檔案等,那麼為什麼我們平時不用定義也會知道去哪找這些東西呢?那是因為gradle有個約定的配置,如果沒有指定,就會使用約定的。所以我們修改這些位置。如下:
sourceSets {
main {
jniLibs.srcDirs = ['libs'] //修改so庫存放的位置
}
}
sourceSets {
main {
//修改資原始檔的位置
// res存放公共的資源,res-ad 存放廣告資源,res-player存放播放器資源
res.srcDirs = ['src/main/res', 'src/main/res-ad', 'src/main/res-player']
}
}