You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使Gradle任务:birds:generateStringResources始终优先执行?

如何让指定Gradle任务始终在所有任务前执行

问题场景

我在项目级build.gradle中添加了以下代码,想要让:birds:generateStringResources任务在任何其他任务之前执行:

tasks.all { Task t ->
    if (t != ':birds:generateStringResources') {
        println("Adding dependsOn(':birds:generateStringResources') to: $t")
        t.dependsOn(':birds:generateStringResources')
    }
}

运行./gradlew trees时,配置阶段的输出显示已经给多个任务添加了依赖:

Configure project :
Adding dependsOn(':birds:generateStringResources') to: task ':build'
Adding dependsOn(':birds:generateStringResources') to: task ':assemble'
Adding dependsOn(':birds:generateStringResources') to: task ':buildDependents'
Adding dependsOn(':birds:generateStringResources') to: task ':buildEnvironment'
etc...

但实际执行时,第一个运行的任务却是:trees:preBuild,而非预期的:birds:generateStringResources:

Task :trees:preBuild UP-TO-DATE // <-- 我希望:birds:generateStringResources在此之前运行
Task :trees:preArm64DebugBuild UP-TO-DATE
Task :trees:mergeArm64DebugNativeDebugMetadata NO-SOURCE
Task :dogs:preBuild UP-TO-DATE
etc...

只有运行./gradlew tasks --all时,:birds:generateStringResources才会作为第一个任务执行:

Task :birds:generateStringResources // 执行成功,这是第一个任务
Task :tasks

后续构建依赖该任务生成的字符串资源,需要实现:无论执行./gradlew后传入什么任务名,:birds:generateStringResources都始终在所有任务之前执行。

解决方案

方法1:监听所有任务创建并添加依赖

原代码的问题在于tasks.all只能捕获配置阶段已经存在的任务,而像模块preBuild这类任务是在子项目配置阶段才动态创建的,不会被原代码覆盖。

改用tasks.whenTaskAdded监听所有任务的创建事件,确保所有任务都添加依赖:

// 项目级build.gradle
def generateTask = tasks.getByPath(':birds:generateStringResources')

allprojects {
    tasks.whenTaskAdded { t ->
        if (t != generateTask) {
            t.dependsOn(generateTask)
        }
    }
}

如果是Android项目,更精准的方式是只让所有preBuild任务依赖它(因为Android构建流程中preBuild是大部分任务的前置):

// 项目级build.gradle
def generateTask = tasks.getByPath(':birds:generateStringResources')

allprojects {
    tasks.whenTaskAdded { t ->
        if (t.name == 'preBuild' && t != generateTask) {
            t.dependsOn(generateTask)
        }
    }
}

方法2:通过任务图强制调整执行顺序

利用Gradle的任务图API,在任务图构建完成后,确保目标任务被加入执行队列,并且所有任务都在它之后运行:

// 项目级build.gradle
def generateTask = tasks.getByPath(':birds:generateStringResources')

gradle.taskGraph.whenReady { graph ->
    // 如果任务图中没有目标任务,主动添加
    if (!graph.hasTask(generateTask)) {
        graph.addTasks([generateTask])
    }
    // 让所有其他任务必须在目标任务之后执行
    graph.allTasks.each { t ->
        if (t != generateTask) {
            t.mustRunAfter(generateTask)
        }
    }
}

注意事项

  • 务必避免给:birds:generateStringResources本身添加依赖,否则会触发循环依赖错误
  • 全局依赖可能会影响构建性能,若能明确哪些任务需要用到生成的资源,优先给这些任务单独设置依赖
  • 如果:birds模块是其他模块的依赖,也可以在:birds模块的build.gradle中让generateStringResources成为preBuild的依赖,这样依赖该模块的项目会自动触发它

内容的提问来源于stack exchange,提问作者h.and.h

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 07:43:22