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

为什么Gradle添加依赖时tasks.all生效但tasks.matching不生效?

Gradle三种元任务写法差异原因

核心背景

Gradle生命周期分为初始化、配置、执行三个阶段,你写的任务配置代码默认在配置阶段执行。而AGP 4.2+的多flavor测试任务(即test[Flavor名]DebugUnitTest)是AGP插件在配置阶段后期才动态生成的,配置testAllFlavors任务时这些任务还不存在。同时Gradle 7.1默认开启任务惰性创建机制,非必要任务不会提前注册到任务容器中。


三种写法的具体差异

第一种写法失效原因

subprojects {
 task("testAllFlavors"){
    val buildTask = this
    tasks.matching {
        name.startsWith("test") && name.endsWith("DebugUnitTest")
        }.all {
        buildTask.dependsOn(this)
}
}
}

tasks.matching{}返回的是一个延迟过滤的任务集合视图,调用它的.all{}方法时,只会对调用该方法瞬间已经存在于任务容器中的任务执行回调。配置testAllFlavors时AGP还没生成flavor测试任务,所以没有符合条件的任务被添加为依赖,后续动态生成的任务也不会被这个回调捕获。

第二种写法失效原因

subprojects {
 task("testAllFlavors"){
setDependsOn(tasks.matching {
           name.startsWith("test") && name.endsWith("DebugUnitTest")
        })
}
}

和第一种问题本质一致,调用setDependsOn时直接传入当前matching得到的空任务集合,后续AGP动态生成的符合条件的任务不会自动同步到这个依赖集合中,因此依赖始终为空。

第三种写法生效原因

subprojects {
 task("testAllFlavors"){
 val buildTask = this
        tasks.all {
            if(name.startsWith("test") && name.endsWith("DebugUnitTest")) {
                buildTask.dependsOn(this)
            }
        }
    }
}

tasks.all{}是给整个任务容器注册了一个全局的任务注册监听器:不管是调用该方法时已经存在的任务,还是之后任何时间(包括配置阶段后期AGP动态生成)新增的任务,都会执行这个回调判断,符合条件的任务就会被添加为依赖,因此能捕获到所有flavor的测试任务。


内容的提问来源于stack exchange,提问作者David Michael Gang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:54:01