为什么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
相关产品推荐
相关产品推荐

