Gradle_04 Task详解

283 阅读3分钟

1.Task创建与配置

如果只是执行helloTask3 ,那么hello task,hello task2,hello task3都会输出,而doLast或者doFirst代码则不会输出

//直接通过task函数去创建
task helloTask{
    println 'hello task'
    doFirst{
        println 'doFirst hello task'
    }
}

//通过taskContainer去创建task
this.tasks.create(name:'helloTask2'){
    println 'hello task2'
    doLast{
        println 'doLast hello task2'
    }
}

//task配置 创建分组和描述信息
task helloTask3(group:'dsh',description:'task study'){
    //或者调用api方法
//    setGroup('gradle')
//    setDescription('task study')
    println 'hello task3'
}

自定义分组后,dsh分组将会出现在Tasks目录下

2. 通过doFist 和 doLast计算build执行阶段的时长代码

//2 doFirst 和 doLast
task helloTask4(group:'dsh',description:'task study4'){
    println 'hello task4'
    doFirst{
        println 'the task group is'+group
    }
    doLast{}
}
helloTask4.doFirst{
    println 'the task description is'+description
}

//3 计算build执行阶段的时长
def startBuildTime,endBuildTime
//配置执行完的回调
this.afterEvaluate { Project project ->
    //保证要找的task已经配置完毕
    def preBuildTask = project.tasks.getByName('preBuild')
    preBuildTask.doFirst {
        startBuildTime = System.currentTimeMillis()
        println 'the start time is :'+startBuildTime//the start time is :1585203044860
    }
    def buildTask = project.tasks.getByName('build')
    buildTask.doLast {
        endBuildTime = System.currentTimeMillis()
        println "the build time is: ${endBuildTime-startBuildTime}"//the build time is: 22684
    }
}

3. Taks依赖

//4 task依赖
task taskX{
    println 'Task X show'
    doFirst{
        println 'Task X'
    }
}
task taskY{
    doLast{
        println 'Task Y'
    }
}
//添加依赖,taskZ在执行的时候先执行X和Y(并且X和Y执行顺序不一定),然后才打印'Task Z'
task taskZ(dependsOn:[taskX,taskY]){
    doLast{
        println 'Task Z'
    }
}
//也可以这样写
//taskZ.dependsOn(taskX,taskY)

//依赖所有以lib开头的task
task taskW{
    dependsOn this.tasks.findAll {
        task -> return task.name.startsWith('lib')
    }
    doLast{
        println 'Task W'
    }
}
//def libs = this.tasks.findAll { task ->
//    return task.name.startsWith('lib')
//}
//taskW dependsOn(libs)
//'<<'追加符等效于doLast
task lib1 <<{
    println 'lib1'
}
task lib2 <<{
    println 'lib2'
}
task nolib <<{
    println 'nolib'
}

4.Task输入输出

尝试向releases.xml中写入版本信息
xml文件

<releases>
    <release>
        <versionCode>100</versionCode>
        <versionName>1.0.0</versionName>
        <versionInfo>App的第1个版本,上线了一些最基础核心的功能.</versionInfo>
    </release>
    <release>
        <versionCode>110</versionCode>
        <versionName>1.1.0</versionName>
        <versionInfo>App的第2个版本,新增了一些功能.</versionInfo>
    </release>
</releases>

新建versionInfo.gradle,实现版本写入

import groovy.xml.MarkupBuilder

/**
 * 版本发布文档自动维护脚本
 * 流程描述:1、请求本次版本相关信息
 *          2、将版本相关信息解析出来
 *          3、将解析出的数据生成xml格式数据
 *          4、写入到已有的文档数据中
 */
ext{
    versionName = rootProject.ext.android.versionName
    versionCode = rootProject.ext.android.versionCode
    versionInfo = 'App的第3个版本,又上了一些新功能'
    destFile = file('releases.xml')
    if(destFile!=null&&!destFile.exists()){
        destFile.createNewFile()
    }
}

//挂载自定义task到构建过程中
this.project.afterEvaluate {project ->
    def buildTask = project.tasks.getByName('build')
    if(buildTask == null){
        throw GradleExecption('the build task is not found')
    }
    buildTask.doLast{
        writeTask.execute()
    }
}

task writeTask{
    //为task指定输入
    inputs.property('versionCode',this.versionCode)
    inputs.property('versionName',this.versionName)
    inputs.property('versionInfo',this.versionInfo)
    //为task指定输出
    outputs.file destFile
    doLast{
        def data = inputs.getProperties()
        File file = outputs.getFiles().getSingleFile()
        //将data转化为实体对象
        def versionMsg = new VersionMsg(data)
        //将实体对象转化为xml格式数据
        def sw = new StringWriter()
        def xmlBuilder = new MarkupBuilder(sw)
        if (file.text !=null &&file.text.size()<=0){
            //文件中没有内容
            xmlBuilder.release{
                release{
                    versionCode(versionMsg.versionCode)
                    versionName(versionMsg.versionName)
                    versionInfo(versionMsg.versionInfo)
                }
            }
            file.withWriter {writer -> weiter.append(sw.toString())}
        }else{
            //已有版本信息
            xmlBuilder.release{
                versionCode(versionMsg.versionCode)
                versionName(versionMsg.versionName)
                versionInfo(versionMsg.versionInfo)
            }
            //将生成的xml数据插入到根节点之前
            def lines = file.readLines()
            def lengths = lines.size()-1
            file.withWriter {writer ->
                lines.eachWithIndex{ String line, int index ->
                    if(index !=lengths){
                        writer.append(line +"\r\n")
                    }else if(index == lengths){
                        writer.append("\r\n"+sw.toString()+"\r\n")
                        writer.append(lines.get(lengths))
                    }
                }
            }
        }
    }

}

task readTask{
    inputs.file destFile
    doLast{
        def file = inputs.files.singleFile
        println file.text
    }
}

class VersionMsg {
    String versionCode
    String versionInfo
    String versionName
}

task taskTest{
    dependsOn readTask,writeTask
    doLast{
        println '输入输出任务结束'
    }
}

5 Task执行顺序

如果不指定XYZ的执行顺序,那么他们的先后执行顺序是不一定的,通过mustRunAfter可以指定task先后执行顺序

//6.mustRunAfter 指定先后执行顺序  X->Y->Z
task taskX{
    doFirst{
        println 'Task X'
    }
}
task taskY{
    mustRunAfter taskX
    doLast{
        println 'Task Y'
    }
}
task taskZ{
    mustRunAfter taskY
    doLast{
        println 'Task Z'
    }
}

6 挂载自定义task到构建工程中

versionInfo.gradle中添加如下代码

//挂载自定义task到构建过程中
this.project.afterEvaluate {project ->
    def buildTask = project.tasks.getByName('build')
    if(buildTask == null){
        throw GradleExecption('the build task is not found')
    }
    buildTask.doLast{
        writeTask.execute()
    }
}

然后在app/build.gradle中导入它,执行./gradlew app:build或者./gradlew build命令

apply from: this.rootProject.file('versionInfo.gradle')