版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huanghuangjin/article/details/82348075
app
// gradlew tasks // 查看工程所有的task,及其描述信息
// 等同于 task('helloTask') {} ,创建task方式一 ,此方式创建的task最终会添加到project的 TaskContainer 中,TaskContainer为Task的管理类
// 创建task时就指定 group、description,会在Gradle面板中对应Porject下的Tasks下看到添加的task的group,如果不指定group名,默认放在other组下
// Task 能配置的属性,参看Task类的成员属性
task helloTask(group: 'hj', description: 'hj task') { Task task ->
println "hello my task : $task.group, $task.description" // 相同group的task会放在同一组,方便管理,description相当于代码注释
// doFIrst 闭包中的代码是在task开始执行前执行,doLast是在task开始执行后执行,没在doFIrst doLast闭包体中的代码块在Gradle配置阶段执行
// doFirst可以写多个,也可在task外部写doFirst, doLast一样 。 用 create 方式创建的task的这些操作也是一样的
doFirst { println "a" }
doFirst { println "b" }
doLast { println "d" }
doLast { println "e" }
}
helloTask.doFirst { println "c" } // c b a , doFirst的执行顺序为编写的反顺序,类似于入栈出栈?
helloTask.doLast { println "f" } // d e f , doLast的执行顺序为编写的正顺序,类似于队列?
this.tasks.create(name: 'helloTask2') { // 创建task方式二,通过 TaskContainer 方式创建,name表示task的名字 。 这两种task创建方式没有区别
setGroup('hj')
setDescription('hj task2')
println 'hello my task2.'
}
// 计算build执行时长(Gradle执行阶段的时长)
def hjstartTime, hjendTime
static def hjgetFormatTime(long time) {
def format = new SimpleDateFormat('yyyy-MM-dd HH:mm:ss')
format.format(new Date(time))
}
this.afterEvaluate { Project project ->
// 获取preBuild task,找不到会报错,findByName 找不到不会报错但是返回null 。 preBuild在hjMedia中会报找不到
def preBuildTask = project.tasks.getByName('preBuild') // preBuild task是Gradle执行阶段开始调用的第一个task
preBuildTask.doFirst {
hjstartTime = System.currentTimeMillis()
}
def buildTask = project.tasks.getByName('build') // 获取build task , build task是Gradle执行阶段最后调用的task
buildTask.doLast {
hjendTime = System.currentTimeMillis()
println "start time=${hjgetFormatTime(hjstartTime)}, end time=${hjgetFormatTime(hjendTime)}, 用时=${(hjendTime-hjstartTime)}"
}
}
// 决定task执行顺序:dependsOn强依赖方式、通过Task输入输出指定、通过API指定执行顺序 转换.dot到task时序图(Graphviz)
// dependsOn强依赖指定
task lib1 << { println 'lib1' } // <<{} 等同于 doLast{}
task lib2 << { println 'lib2' }
task nolib << { println 'nolib' }
task taskX { doLast { println 'taskX' } }
task taskY { doLast { println 'taskY' } }
task taskZ(dependsOn:[taskX, taskY]) { // 静态依赖taskX taskY 多个依赖用list,依赖的task的执行顺序随机, dependsOn:taskY 表示单个依赖
dependsOn this.tasks.findAll { // 动态依赖 task
task -> return task.name.startsWith('lib') // 依赖TaskContainer中所有名以 lib 开头的task 。 lib1 lib2 定义在此后面在这里的tasks中可能会找不到
}
doLast { println 'taskZ' }
}
//taskZ.dependsOn taskX, taskY // 等同于 taskZ.dependsOn(taskX, taskY) 、 taskZ(dependsOn:[taskX, taskY]) , Gradle函数的参数可以不用()而用 空格
task hjparseXml {
def srcFile = file('testTask.xml')
doLast {
if (srcFile!=null && srcFile.text.size()>0) {
def releases = new XmlParser().parse(srcFile) // XmlParser解析xml,parse() 返回值为xml的根节点
releases.release.each { releaseNode -> // 遍历根节点下的子节点
println "hjversionName=${releaseNode.hjversionName.text()}, hjversionInfo=${releaseNode.hjversionInfo.text()}"
}
}
}
}
// 通过Task输入输出指定
ext {
hjversionName = '1.0.1'
hjversionCode = '101'
hjversionInfo = 'test1.0.1'
hjdstFile = file('testTask.xml')
if (hjdstFile!=null && !hjdstFile.exists()) hjdstFile.createNewFile()
}
class hjVersionMsg { // xml节点对应数据结构
String hjversionName
String hjversionCode
String hjversionInfo
}
task hjwriteTask {
inputs.property('hjversionName', this.hjversionName) // 为Task 指定输入,key value 形式
inputs.properties([hjversionCode: this.hjversionCode, hjversionInfo: this.hjversionInfo]) // 以map形式设置输入
outputs.file hjdstFile // 为 Task 指定输出
doLast {
def data = inputs.getProperties() // 将所有输入以map的形式返回
File file = outputs.getFiles().getSingleFile() // outputs.getFiles() 获取所有输出文件,这里是有一个,所以 getSingleFile()
def versionMsg = new hjVersionMsg(data) // 以 map 创建 hjVersionMsg 对象
def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw)
if (file.text!=null && file.text.size()<=0) {
xmlBuilder.releases { // 根节点
release { // 子节点
hjversionName(versionMsg.hjversionName) // 子节点
hjversionCode(versionMsg.hjversionCode)
hjversionInfo(versionMsg.hjversionInfo)
}
}
file.withWriter { writer -> writer.append(sw.toString()) } // 往文件中追加 StringWriter 的内容
} else {
xmlBuilder.release { // 文件已存在且内容不为空时就不用创造xml根节点了
hjversionName(versionMsg.hjversionName)
hjversionCode(versionMsg.hjversionCode)
hjversionInfo(versionMsg.hjversionInfo)
}
def lines = file.readLines()
def lens = lines.size()-1
file.withWriter { writer ->
lines.eachWithIndex { String line, int index ->
if (index==lens) { // 文件最后一行之前添加新的xml节点
writer.append('\r\n'+sw.toString()+'\r\n')
}
writer.append(line+'\r\n')
}
}
}
println 'hjwriteTask end.'
}
}
task hjreadTask {
inputs.file hjdstFile // hjwriteTask 与 hjreadTask 通过输入输出的 hjdstFile 关联了起来,即hjreadTask依赖了hjwriteTask
doLast {
def file = inputs.files.singleFile
println "outputs : ${file.text}"
}
}
task hjtestWR {
dependsOn hjreadTask, hjwriteTask
doLast {
println '输入输出Task结束'
}
}
// 通过API指定执行顺序
task taskA { doLast { println 'taskA' } }
task taskB {
mustRunAfter taskA // mustRunAfter 表示 taskC 运行必须在 taskA 运行之后 ,mustRunAfter 也接受多个task,逗号隔开
doLast { println 'taskB' }
}
task taskC {
// 运行 gradlew taskC taskB taskA 命令执行这三个task,gradlew后的task顺序不管怎么变,执行都是按的 A B C
// 如果只 gradlew taskC , 那么指挥运行 taskC
mustRunAfter taskB
// shouldRunAfter taskB // shouldRunAfter 与 mustRunAfter 效果一样,只是 shouldRunAfter 不是强制要求,mustRunAfter 是强制要求
doLast { println 'taskC' }
}
//this.afterEvaluate {
// def buildTask = this.tasks.getByName('build')
// buildTask.doLast { // gradlew build 完之后执行 hjwriteTask
// hjwriteTask.execute() // execute() 表示执行task
// }
//}
// 如果想将某task插入到project生命周期的执行阶段中间,那么可以找到想插入的位置的前后两个task,然后利用 mustRunAfter 与 dependsOn 即可完成插入
// Task的类型,默认是DefaultTask 其他类型参看 https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html 官方文档