Gradle - 任务
Gradle 构建脚本描述了一个或多个项目。每个项目都由不同的任务组成,而任务是构建执行的一项工作。
任务可能是编译一些类,将类文件存储到单独的目标文件夹中,创建 JAR,生成 Javadoc 或将一些存档发布到存储库。
本章解释了什么是任务以及如何生成和执行任务。
定义任务
Task 是一个关键字,用于在构建脚本中定义任务。
请查看以下示例,它表示一个名为 hello 的任务,该任务打印 tutorialspoint。将以下脚本复制并保存到名为 build.gradle 的文件中。
此构建脚本定义了一个名为 hello 的任务,用于打印 tutorialspoint 字符串。
task hello { doLast { println 'tutorialspoint' } }
在命令提示符中执行以下命令。它执行上述脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q hello
输出
\以下是代码的输出:
tutorialspoint
您可以通过为 doLast 语句指定一个快捷方式(表示符号 <<)来简化此 hello 任务。如果您将此快捷方式添加到上面的 hello 任务,它将如下所示:
task hello << { println 'tutorialspoint' }
您可以使用 gradle –q hello 命令执行上述脚本。
以下示例定义了一个名为 hello 的任务。
将以下代码复制并保存到 build.gradle 文件中。
task (hello) << { println "tutorialspoint" }
在命令提示符中执行以下命令。它执行上面给出的脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q hello
输出
输出如下所示:
tutorialspoint
您还可以使用字符串作为任务名称。请查看相同的 hello 示例。在这里,我们将使用 String 作为任务。
将以下代码复制并保存到 build.gradle 文件中。
task('hello') << { println "tutorialspoint" }
在命令提示符中执行以下命令。它执行上面提到的脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q hello
输出
执行上述代码后,您应该会看到以下输出:
tutorialspoint
您还可以使用另一种语法来定义任务。即,使用 create() 方法来定义任务。请查看下面给出的相同的 hello 示例。
将下面给出的代码复制并保存到 build.gradle 文件中。
tasks.create(name: 'hello') << { println "tutorialspoint" }
在命令提示符中执行以下命令。它执行上面陈述的脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q hello
输出
执行后,您将收到以下输出:
tutorialspoint
查找任务
如果您想查找在构建文件中定义的任务,则必须使用相应的标准项目属性。这意味着每个任务都作为项目的属性可用,其中任务名称用作属性名称。
请查看以下代码,该代码将任务作为属性访问。
将下面给出的代码复制并保存到 build.gradle 文件中。
task hello println hello.name println project.hello.name
在命令提示符中执行以下命令。它执行上面给出的脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q hello
输出
输出如下所示:
hello hello
您还可以通过 tasks 集合使用所有属性。
将以下代码复制并保存到 build.gradle 文件中。
task hello println tasks.hello.name println tasks['hello'].name
在命令提示符中执行以下命令。它执行上面提到的脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q hello
输出
这将产生以下输出:
hello hello
您还可以通过 tasks 访问任务的路径。为此,您可以使用任务名称、相对路径或绝对路径调用 getByPath() 方法。
将下面给出的代码复制并保存到 build.gradle 文件中。
project(':projectA') { task hello } task hello println tasks.getByPath('hello').path println tasks.getByPath(':hello').path println tasks.getByPath('projectA:hello').path println tasks.getByPath(':projectA:hello').path
在命令提示符中执行以下命令。它执行上面给出的脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q hello
输出
输出如下所示:
:hello :hello :projectA:hello :projectA:hello
向任务添加依赖项
您可以使一个任务依赖于另一个任务,这意味着,当一个任务完成后,另一个任务才会开始。
每个任务都通过任务名称进行区分。任务名称的集合由其 tasks 集合引用。要引用另一个项目中的任务,您应该使用项目的路径作为相应任务名称的前缀。
以下示例将 taskX 的依赖项添加到 taskY。
将下面给出的代码复制并保存到 build.gradle 文件中。请查看以下代码。
task taskX << { println 'taskX' } task taskY(dependsOn: 'taskX') << { println "taskY" }
在命令提示符中执行以下命令。它执行上面陈述的脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q taskY
输出
输出如下所示:
taskX taskY
上面的示例是使用任务名称添加任务依赖项。还有另一种方法可以实现任务依赖项,即使用 Task 对象定义依赖项。
让我们以 taskY 依赖于 taskX 为例,但在这里,我们使用的是任务对象而不是任务引用名称。
将以下代码复制并保存到 build.gradle 文件中。
task taskY << { println 'taskY' } task taskX << { println 'taskX' } taskY.dependsOn taskX
在命令提示符中执行以下命令。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q taskY
输出
输出如下所示:
taskX taskY
上面的示例是使用任务名称添加任务依赖项。
还有另一种方法可以实现任务依赖项,即使用 Task 对象定义依赖项。
在这里,我们以 taskY 依赖于 taskX 为例,但是,我们使用的是任务对象而不是任务引用名称。
将下面给出的代码复制并保存到 build.gradle 文件中。请查看以下代码。
task taskX << { println 'taskX' } taskX.dependsOn { tasks.findAll { task → task.name.startsWith('lib') } } task lib1 << { println 'lib1' } task lib2 << { println 'lib2' } task notALib << { println 'notALib' }
在命令提示符中执行以下命令。它执行上面给出的脚本。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q taskX
输出
输出如下所示:
lib1 lib2 taskX
添加描述
您可以向任务添加描述。执行 Gradle tasks 时会显示此描述,这可以通过使用 description 关键字来实现。
将以下代码复制并保存到 build.gradle 文件中。请查看以下代码。
task copy(type: Copy) { description 'Copies the resource directory to the target directory.' from 'resources' into 'target' include('**/*.txt', '**/*.xml', '**/*.properties') println("description applied") }
在命令提示符中执行以下命令。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q copy
如果命令成功执行,您将获得以下输出
description applied
跳过任务
可以通过传递一个谓词闭包来跳过任务。只有在任务的方法或闭包在执行任务的实际工作之前抛出 StopExecutionException 时,这才有可能。
将以下代码复制并保存到 build.gradle 文件中。
task eclipse << { println 'Hello Eclipse' } // #1st approach - closure returning true, if the task should be executed, false if not. eclipse.onlyIf { project.hasProperty('usingEclipse') } // #2nd approach - alternatively throw an StopExecutionException() like this eclipse.doFirst { if(!usingEclipse) { throw new StopExecutionException() } }
在命令提示符中执行以下命令。您应该在存储 build.gradle 文件的位置执行此操作。
C:\> gradle –q eclipse
任务结构
在处理任务时,Gradle 有不同的阶段。首先,有一个 配置阶段,其中直接在任务的闭包中指定的代码将被执行。配置块将为每个可用的任务执行,而不仅仅是为了那些稍后实际执行的任务。
在配置阶段之后,执行阶段将运行那些实际执行的任务的 doFirst 或 doLast 闭包内的代码。