执行gradle的JAVAhome gradle 执行task_xml


Task

命令行输出gradlew tasks 查看当前工程下所有的task文件

Task 定义与配置两种方式

  • 直接通过task函数进行创建,对task进行配置
  • 通过TaskContainer 进行创建,调用tasks.create
/**
 * 创建task:定义与配置
 */
//直接通过task函数进行创建,对task进行配置
task hellotask(group:'immoc',description:'task study'){
    println "hello task"
}

//通过TaskContainer 进行创建 TaskContainer进行查找与创建
this.tasks.create(name: 'hellotask2'){
    //或者在闭包中进行定义
    setGroup('immoc')
    setDescription('task study')
    println 'i am task2'
}


task 进行分组就会放到对应的group组下面,如果不进行分组就会放到other文件夹下


执行gradle的JAVAhome gradle 执行task_xml_02


Task 执行

在task定义的函数中,使用group进行分组,也可以使用description进行当前task任务描述


/**
 * 在执行阶段进行输出
 */
task tasktest(group:'immoc',description: 'task test'){
    //在配置阶段输出
    println 'hello tasktest'
    //在执行阶段进行输出,doFirst在有了task之前进行逻辑处理,而doLast是在task之后进行逻辑处理
    doFirst{
        println 'the task group is : '+group
    }
}

//或者通过方法闭包进行调用,也是在执行阶段进行输出,但是闭包中输出的速度优先于上面单独通过task调用进行输出
tasktest.doFirst{
    println 'the description is : '+description
}


实战一个计算build执行时长的gradle脚本


/**
 * 计算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"
    }

    def buildTask = project.tasks.getByName('build')
    buildTask.doLast {
        endBuildTime = System.currentTimeMillis()
        println "the build time is ${endBuildTime - startBuildTime}"
    }
}


Task 依赖

  • task 依赖属性使用的是dependsOn,比如下面taskZ 依赖于X与Y,那么他们将会优先于Z进行输出,并且输出它所依赖的task,X与Y是随机顺序执行,由于没有定义依赖关系
  • task 可以自定义依赖所有以lib为开头的库 动态添加依赖,匹配以lib开头的库必须使用startsWithAny ,使用startsWith无法匹配到
/**
 * Task 依赖 dependsOn
 */
task taskX{
    doLast{
        println 'taskX'
    }
}

task taskY{
    doLast{
        println 'taskY'
    }
}

task lib1 {
    doLast {
        println 'lib1'
    }
}

task lib2 {
    doLast {
        println 'lib2'
    }
}

task noLib {
    doLast {
        println 'noLib'
    }
}

//taskZ 依赖于X与Y,那么他们将会优先于Z进行输出,并且输出它所依赖的task,X与Y是随机顺序执行,由于没有定义依赖关系
task taskZ{
    //task依赖于所有以lib为开头的库 动态添加依赖
    dependsOn this.tasks.findAll {task ->
        //这里匹配以lib开头的库必须使用startsWithAny ,使用startsWith无法匹配到
        return task.name.startsWithAny('lib')
    }
    doLast{
        println 'taskZ'
    }
}
//或者通过调用task的dependsOn方法进行依赖 静态添加依赖
//taskZ.dependsOn(taskX,taskY)
/**
 * 依赖实战
 */
task handleReleasTaskFile{
    def srcFile = file('releases.xml')
    def destinationFile = new File(this.buildDir,'generated/release/')
    doLast{
        println '开始解析xml文件'
        destinationFile.mkdir()
        def releaseFile = new XmlParser().parse(srcFile)
        releaseFile.release.each{releaseNode->
            //解析每个节点的内容
            def name = releaseNode.versionName.text()
            def versionCode = releaseNode.versionCode.text()
            def versionInfo = releaseNode.versionInfo.text()
            //创建文件并写入节点数据
            def destFile = new File(destinationFile,"release-${name}.text")
            destFile.withWriter {writer->
                writer.write("$name -> $versionCode -> $versionInfo")
            }
        }
    }
}

//自定义一个测试依赖于handleReleasTaskFile
task handleReleaseFileTest(dependsOn:handleReleasTaskFile){
    def dir = fileTree(this.buildDir + 'generated/release/')
    doLast{
        dir.each {
            println "the file name is:"+it
        }
        println '输出完成'
    }
}


Task 输入输出

自定义一个版本发布文档维护脚本 1. 请求本次版本信息 2. 将版本信息解析出来 3. 将解析出来的数据生成xml格式数据 4. 写入已有的文档数据中 MarkupBuilder不存在导入 import groovy.xml.MarkupBuilder


/** 版本发布文档维护脚本
 * 1. 请求本次版本信息
 * 2. 将版本信息解析出来
 * 3. 将解析出来的数据生成xml格式数据
 * 4. 写入已有的文档数据中
 * task 输入输出详解
 */
ext{
    versionName = '1.0.0'
    versionCode = '100'
    versionInfo = 'App 第一版本,上线一些基础功能'
    destFile = file('releases.xml')
    if(destFile!=null&&!destFile.exists()){
        destFile.createNewFile()
    }
}
/**
 * 在build任务后执行writeTask 任务
 */
this.project.afterEvaluate {project->
    def buildTask = project.tasks.getByName('build')
    if(buildTask==null){
        throw GradleException('the build task is not found')
    }
    buildTask.doLast{
        writeTask.execute()
    }
}
task writeTask{
    //为 task 指定输入
    inputs.property('versionName',this.versionName)
    inputs.property('versionCode',this.versionCode)
    inputs.property('versionInfo',this.versionInfo)
    //为task 指定输出
    outputs.file destFile
    doLast {
        def data = inputs.getProperties()
        def file = outputs.getFiles().getSingleFile()
        //将map转换成实体对象
        def versionMsg = new VersionMsg(data)
        //将实体对象转换成xml对象
        def sw = new StringWriter()
        def xmlBuilder = new MarkupBuilder(sw)
        if(file!=null&&file.size()<=0){
            //文件中没有内容
            xmlBuilder.releases{
                release{
                    versionName(versionMsg.versionName)
                    versionCode(versionMsg.versionCode)
                    versionInfo(versionMsg.versionInfo)
                }
            }
            file.withWriter {writer-> writer.append(sw.toString())}
        }else{
            //已有版本信息
          xmlBuilder.release{
                versionName(versionMsg.versionName)
                versionCode(versionMsg.versionCode)
                versionInfo(versionMsg.versionInfo)
            }
            def lines = file.readLines()
            def lengths = lines.size()-1
            file.withWriter { writer->
                lines.eachWithIndex{ String line, int index ->
                    if(index!=lengths){
                        writer.append(line+'rn')
                    }else if(index==lengths){
                        writer.append('rrn'+sw,toString()+'rn')
                        writer.append(lines.get(lengths))
                    }
                }
            }
        }
    }
}

task readTask{
    //指定输出文件为上一个task的输出
    inputs.file destFile
    doLast{
        def file = inputs.files.singleFile
        println file.text
    }
}

class VersionMsg{
    String versionName
    String versionCode
    String versionInfo
}

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


指定执行顺序,通过mustRunAfter属性指定几个task执行顺序


/**
 * 指定执行顺序
 */
task taskX{
    doLast{
        println 'taskX'
    }
}

task taskY{
    mustRunAfter taskX
    doLast{
        println 'taskY'
    }
}

task taskZ{
    mustRunAfter taskY
    doLast{
        println 'taskZ'
    }
}


SourceSets

  • 只是对默认的文件位置进行修改,从而让gradle知道每种文件从哪个文件夹下查找
  • 可以调用多次sourceSets
  • sourceSets也可以在android包外进行定义
//可以调用多次sourceSets
 sourceSets {
        main{
            jniLibs.srcDirs = ['libs']//修改so库存放位置
        }
    }

    sourceSets {
        main{
            res.srcDirs = ['src/main/res','src/main/res-add','src/main/res-player']//设置资源文件夹的路径为这三个
        }
    }
//sourceSets也可以在android包外进行定义
this.android.sourceSets{
    main{
        res.srcDirs = ['src/main/res','src/main/res-add','src/main/res-player']//设置资源文件夹的路径为这三个
    }
}


Android 对gradle进行扩展

扩展属性使用,使用android下的applicationVariants,应用变体进行输出对gradle扩展


this.afterEvaluate {
    //获取应用变体的一些属性
    this.android.applicationVariants.all{variant->
// def name = variant.name
// def baseName = variant.baseName
// println "the name is ${name}," + "the baseName is ${baseName}"
        //修改apk默认输出的名字
// def output = variant.outputs.first()
// def apkName = "apk-${variant.baseName}"+"-${variant.versionName}.apk"
// output.outputFile = new File(output.outputFile.parent,apkName)
// println output.outputFile.name
        //将不同变体的名字进行区分,每个变体对应一个CheckManifest
        def task = variant.getCheckManifestProvider()
        println task.name
    }
}Gradle