Gradle自动化构建(十) Task

版权声明:本文为博主原创文章,未经博主允许不得转载。 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 官方文档

猜你喜欢

转载自blog.csdn.net/huanghuangjin/article/details/82348075