Gradle入门系列(四)——初识Gradle Task
Gradle中的Task
一、Task定义及配置
TaskContainer:管理所有的Task,如:添加、查找。
定义(创立)Task
// 直接通过task函数去创立task helloTask { println 'i am helloTask.'}// 通过TaskContainer去创立this.tasks.create(name: 'helloTask2') { println 'i am helloTask 2.'}配置Task
// 给Task指定分组与形容task helloTask(group: 'study', description: 'task study'){ // 语法糖 ...}task helloTask { group 'study' // setGroup('study') description 'task study' // setDescription('task study') ...}Task除了可以配置group、description外,还可以配置name、type、dependsOn、overwrite、action。
结论:
- 给Task分组之后,该task会被放到指定组中,方便归类查找。(默认被分组到other中)
- 给Task增加形容,相当于给方法增加注释。
二、Task的执行介绍
Task中doFirst与doLast的使用:
task helloTask { println 'i am helloTask.' doFirst { println 'the task group is: ' + group } // doFirst、doLast可以定义多个 doFirst {}}// 外部指定doFirst(会比在闭包内部指定的doFirst先执行)helloTask.doFirst { println 'the task description is: ' + description}// 统计build执行时长def startBuildTime, endBuildTimethis.afterEvaluate { Project project -> // 保证要找的task已经配置完毕 def preBuildTask = project.tasks.getByName('preBuild') // 执行build任务时,第一个被执行的Task preBuildTask.doFirst { startBuildTime = System.currentTimeMillis() } def buildTask = project.tasks.getByName('build') // 执行build任务时,最后一个被执行的Task buildTask.doLast { endBuildTime = System.currentTimeMillis() println "the build time is: ${endBuildTime - startBuildTime}" }}结论:
- Task闭包中直接编写的代码,会在配置阶段执行。可以通过doFirst、doLast块将代码逻辑放到执行阶段中执行。
- doFirst、doLast可以指定多个。
- 外部指定的doFirst、doLast会比内部指定的先执行。
- doFirst、doLast可以对gradle中提供的已有的task进行扩展。
三、Task的执行顺序
task执行顺序指定的三种方式:
- dependsOn强依赖方式
- 通过Task输入输出指定(与第1种等效)
- 通过API指定执行顺序
1、Task的依赖
// ============= dependsOn强依赖方式 =============task taskX { doLast { println 'taskX' }}task taskY { doLast { println 'taskY' }}// 方式一:静态依赖// task taskZ(dependsOn: taskY) // 依赖一个tasktask taskZ(dependsOn: [taskX, taskY]) { // 依赖多个task,需要用数组[]表示 doLast { println 'taskZ' }}// 方式二:静态依赖taskZ.dependsOn(taskX, taskY)// 方式三:动态依赖task taskZ() { dependsOn this.tasks.findAll { // 依赖所有以lib开头的task task -> return task.name.startsWith('lib') } doLast { println 'taskZ' }}其余:
- taskZ依赖了taskX与taskY,所以在执行taskZ时,会先执行taskX、taskY。
- taskZ依赖了taskX与taskY,但taskX与taskY没有关系,它们的执行顺序是随机的。
2、Task的输入输出

inputs和outputs是Task的属性。
inputs可以是任意数据类型对象,而outputs只能是文件(或者文件夹)。
TaskA的outputs可以作为TaskB的inputs。
例子:writeTask输入扩展属性,输出文件,readTask输入writeTask的输出文件
ext { versionCode = '1.0.0' versionName = '100' versionInfo = 'App的第1个版本,完成聊天功能' destFile = file('release.xml') if (destFile != null && !destFile.exists()) { destFile.createNewFile() }}task writeTask { inputs.property('versionCode', this.versionCode) inputs.property('versionName', this.versionName) inputs.property('versionInfo', this.versionInfo) outputs.file this.destFile doLast { def data = inputs.getProperties() // 返回一个map File file = outputs.getFiles().getSingleFile() // 将map转为实体对象 def versionMsg = new VersionMsg(data) def sw = new StringWriter() def xmlBuilder = new MarkupBuilder(sw) if (file.text != null && file.text.size() <= 0) { // 文件中没有内容 // 实际上,xmlBuilder将xml数据写入到sw中 xmlBuilder.releases { // <releases> release { // <releases>的子节点<release> versionCode(versionMsg.versionCode) // <release>的子节点<versionCode>1.0.0<versionCode> versionName(versionMsg.versionName) versionInfo(versionMsg.versionInfo) } } // 将sw里的内容写到文件中 file.withWriter { writer -> writer.append(sw.toString()) } } else { // 已经有其它版本信息了 xmlBuilder.release { versionCode(versionMsg.versionCode) versionName(versionMsg.versionName) 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 + '\r\n') } else if (index == lengths) { writer.append(sw.toString() + '\r\n') writer.append(line + '\r\n') } } } } }}task readTask { inputs.file destFile doLast { def file = inputs.files.singleFile println file.text }}task taskTest(dependsOn: [writeTask, readTask]) { doLast { println '任务执行完毕' }}class VersionMsg { String versionCode String versionName String versionInfo}通过执行 gradle taskTask 之后,即可以在工程目录下看到release.xml文件了。
结论:
- 由于writeTask与readTask通过inputs、outputs产生了关联关系,所以,readTask肯定会在writeTask执行之后才执行。
3、Task API指定顺序
task指定执行顺序的api有:
- mustRunAfter : 强行指定在某个或者某些task执行之后才执行。
- shouldRunAfter : 与mustRunAfter一样,但不强制。
task taskX { doLast { println 'taskX' }}task taskY { // shouldRunAfter taskX mustRunAfter taskX doLast { println 'taskY' }}task taskZ { mustRunAfter taskY doLast { println 'taskZ' }}通过执行 gradle taskY taskZ taskX 之后,可以看到终端还是按taskX、taskY、taskZ顺序执行的。
四、挂接到构建生命周期
例子:build任务执行完成后,执行一个自己设置task
this.afterEvaluate { Project project -> def buildTask = project.tasks.getByName('build') if (buildTask == null) throw GradleException('the build task is not found') buildTask.doLast { taskZ.execute() }}例子:Tinker将自己设置的manifestTask插入到了gradle脚本中processManifest与processResources这两个任务之间
TinkerManifestTask manifestTask = project.tasks.create("tinkerProcess${variantName}Manifest", TinkerManifestTask)...manifestTask.mustRunAfter variantOutput.processManifestvariantOutput.processResources.dependsOn manifestTask五、Task类型
Gradle DSL Version 5.1
Copy – Gradle DSL Version 5.1
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Gradle入门系列(四)——初识Gradle Task
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Gradle入门系列(四)——初识Gradle Task