用全名才能准确定位任务,因为Gradle多模块中短名称(如test)会重复,需用“模块路径:任务名”格式(如:app:assembleDebug)明确作用域,避免执行错误模块任务。

为什么用全名才能准确定位任务
Gradle 在多模块项目中默认只显示任务的“短名称”,比如 build、test,但这些名称在不同子项目里可能重复存在。当你运行 ./gradlew test,Gradle 会按当前工作目录和项目结构决定作用域——如果没明确指定,它可能只在根项目或当前模块里找,而忽略其他同名但路径不同的任务。更麻烦的是,某些 IDE(如 IntelliJ)的 Gradle 工具窗口点击任务时,底层调用的其实是不带路径的短名,容易误触发错误模块的任务。
任务全名的构成规则
Gradle 任务全名 = 模块路径:任务名,其中模块路径以冒号分隔,开头带冒号,结尾不带冒号。例如:
-
:app:assembleDebug表示app模块下的assembleDebug任务 -
:lib:network:compileJava是lib/network子项目里的编译任务 -
:clean是根项目的 clean 任务(注意开头的冒号不能省)
关键点:settings.gradle 中声明的项目路径(如 include ':lib:network')直接决定了该子项目的前缀,不是文件夹名,也不是 build.gradle 所在路径的随意推断。
命令行中必须用全名的典型场景
以下情况不加前缀大概率出错:
- 执行某个子模块独有的任务,比如
:feature:login:generateMockData,而根项目没有同名任务 - 多个子模块都有
test,但你想只跑:core:test,不连带触发:ui:test - 自定义任务名与内置任务冲突,比如你在
:shared里定义了task build { ... },那./gradlew build会优先走根项目的build,而不是你的;必须写成./gradlew :shared:build - CI 脚本里避免环境依赖:显式写全名可防止因工作目录切换导致任务执行错位
容易被忽略的坑:IDE 同步后仍不识别全名任务
即使你写了正确的全名,也可能遇到 Task 'xxx' not found in root project 'yyy'。常见原因有:
-
settings.gradle里漏写了对应子项目,比如忘了include ':lib:network',那:lib:network:xxx根本不存在 - 子项目
build.gradle文件里没启用对应插件(如 Java 插件),导致compileJava这类任务未被注册 - IDE 缓存了旧的项目结构,点击 Gradle 面板刷新按钮没用,得手动触发
File → Sync Project with Gradle Files - 任务定义在
subprojects或allprojects块里,但某个子项目被evaluationDependsOnChildren()类机制跳过,导致任务未实际创建
最稳的验证方式是终端里执行 ./gradlew tasks --all | grep "your-task-name",看输出里是否真有带完整路径的那一行——别信 IDE 的自动补全列表。











