Gradle如何实现任务在另一任务的doLast执行完成后运行
问题根因
Gradle 构建分为配置阶段和执行阶段两个核心阶段,你遇到的问题就是代码执行时机和预期不符导致的:
- 配置阶段会按脚本从上到下的顺序,执行所有任务配置块(
task 任务名{}大括号内,没有被doFirst/doLast包裹的代码),这个阶段不管你最终要执行哪个任务,所有任务的配置代码都会全部跑完。 - 执行阶段才会按照依赖规则、
mustRunAfter这类顺序约束,执行任务的doFirst、doLast等动作。
你当前代码的实际执行时序如下:
- 配置阶段初始化
xy为0 - 解析
callOne的配置块,直接执行xy = xy +5,xy变为5(这步在配置阶段就完成了,和callOne是否执行无关) - 解析
callTwo的配置块,仅注册doLast动作,没有立即执行的代码,xy保持5不变 - 解析
callThree的配置块,直接执行println "xy : $xy",此时就输出了5,这就是你看到的错误结果,这一步发生时执行阶段还未启动 - 配置阶段结束,开始执行
callAll任务 - 按你配置的顺序先执行
callOne,但callOne没有定义执行阶段的动作,无任何操作 - 接着执行
callTwo的doLast动作,xy加5变为10 - 最后执行
callThree,但callThree也没有定义执行阶段的动作,无任何操作
你配置的mustRunAfter规则仅作用于执行阶段的任务顺序,对配置阶段就已经执行的打印逻辑完全不生效,所以无法解决问题。
解决方案
在不修改三个基础任务原有定义的前提下,我们只需要把打印逻辑放到执行阶段的末尾即可,有两种可行方式:
方式1:给callThree追加执行阶段动作
task callAll(){ dependsOn 'callOne' dependsOn 'callTwo' dependsOn 'callThree' tasks.findByName('callTwo').mustRunAfter 'callOne' tasks.findByName('callThree').mustRunAfter 'callTwo' // 追加执行阶段的打印逻辑,拿到最终计算后的xy值 tasks.callThree.doLast { println "xy : $xy" } }
执行后会先输出配置阶段的xy : 5,然后输出执行阶段的正确结果xy : 10。
方式2:在callAll的执行阶段末尾打印
如果不想看到配置阶段的冗余打印,可以直接在callAll的doLast里输出结果:
task callAll(){ dependsOn 'callOne' dependsOn 'callTwo' dependsOn 'callThree' tasks.findByName('callTwo').mustRunAfter 'callOne' tasks.findByName('callThree').mustRunAfter 'callTwo' doLast { println "xy : $xy" } }
执行callAll后,最后输出的就是正确的10。
内容的提问来源于stack exchange,提问作者dev.Manderson
相关产品推荐
相关产品推荐

