Introduction to the
In previous articles, we talked about how to use Gradle to create simple tasks, how tasks depend on each other, and even how to use programs to create tasks. In this article, we’ll take a closer look at Tasks in Gradle.
Define the task
There are several ways to define a task, such as using a string as the task name:
task('hello') {
doLast {
println "hello"
}
}
task('copy', type: Copy) {
from(file('srcDir'))
into(buildDir)
}
Copy the code
Tasks can also be created using the Tasks container:
tasks.create('hello') {
doLast {
println "hello"
}
}
tasks.create('copy', Copy) {
from(file('srcDir'))
into(buildDir)
}
Copy the code
In the above example, we use the tasks.create method to add the newly created task to the Tasks collection.
We can also define a task using Groovy’s unique syntax:
task(hello) {
doLast {
println "hello"
}
}
task(copy, type: Copy) {
from(file('srcDir'))
into(buildDir)
}
Copy the code
The tasks collection class
The Tasks collection class is used to create tasks.
In fact, the Tasks collection class is a very useful utility class that we can use to do a lot of things.
Using Tasks directly in the build file actually references an instance object of TaskContainer. We can also use project.gettasks () to get the instance object.
Let’s take a look at the TaskContainer definition:
public interface TaskContainer extends TaskCollection<Task>, PolymorphicDomainObjectContainer<Task>
Copy the code
By definition, TaskContainer is a collection of tasks and domain objects.
There are four types of methods that are very important in taskContainer:
The first type is the method that locates the task, which is findByPath and getByPath. The difference between the two methods is that findByPath returns null if it’s not found, and getByPath throws UnknownTaskException if it’s not found.
See how to use it:
task hello
println tasks.getByPath('hello').path
println tasks.getByPath(':hello').path
Copy the code
Output:
:hello
:hello
Copy the code
The second type is the create task method. The create method has multiple implementations, and you can create a task by name:
task('hello') {
doLast {
println "hello"}}Copy the code
You can also create a specific type of task:
task('copy', type: Copy) {
from(file('srcDir'))
into(buildDir)
}
Copy the code
You can also create a task with an argument constructor:
class CustomTask extends DefaultTask {
final String message
final int number
@Inject
CustomTask(String message, int number) {
this.message = message
this.number = number
}
}
Copy the code
We created a constructor for CustomTask with parameters. Note that we need to annotate @javax.inject.Inject to indicate that we can pass parameters to the constructor later.
We can use it like this:
tasks.create('myTask', CustomTask, 'hello'.42)
Copy the code
It can also be used like this:
task myTask(type: CustomTask, constructorArgs: ['hello'.42])
Copy the code
The third type is register, which is also used to create new tasks, but registers perform deferred creation. That is, tasks are created only when they are needed.
Let’s look at the definition of a register method:
TaskProvider<Task> register(String name,
Action<? super Task> configurationAction)
throws InvalidUserDataException
Copy the code
The Register returns a TaskProvider, similar to the Callable in Java multithreading, which is created when we call provider.get () to get the task value.
Or when we call TaskCollection.getByName(java.lang.string), the corresponding task will be created.
The last type is the replace method:
Task replace(String name)
<T extends Task> T replace(String name,
Class<T> type)
Copy the code
Replace creates a new task and replaces an old task with the same name.
Dependencies between tasks
Dependencies between tasks are determined by task name. We can do dependencies between tasks in the same project:
task hello {
doLast {
println 'Hello www.flydean.com! '
}
}
task intro {
dependsOn hello
doLast {
println "I'm flydean"}}Copy the code
Task dependencies can also be made across projects. If the task dependencies are made across projects, the path of the task needs to be specified:
project('project-a') {
task taskX {
dependsOn ':project-b:taskY'
doLast {
println 'taskX'
}
}
}
project('project-b') {
task taskY {
doLast {
println 'taskY'}}}Copy the code
Or we can deal with dependencies between tasks after we have defined them:
task taskX {
doLast {
println 'taskX'
}
}
task taskY {
doLast {
println 'taskY'}}Copy the code
Dependencies can also be added dynamically:
task taskX {
doLast {
println 'taskX'}}// Using a Groovy Closure
taskX.dependsOn {
tasks.findAll { task -> task.name.startsWith('lib') }
}
task lib1 {
doLast {
println 'lib1'
}
}
task lib2 {
doLast {
println 'lib2'
}
}
task notALib {
doLast {
println 'notALib'}}Copy the code
Define the order between tasks
Sometimes our tasks have an order of execution. This is called ordering tasks.
Take a look at the difference between ordering and dependency. Dependency represents a strong dependency. If taskA depends on taskB, taskB must be implemented before taskA.
The ordering is not too strong. Indicates that taskA needs to be executed after taskB, but taskB can be executed without it.
Gradle has two orders: must run after and should run after.
TaskA. MustRunAfter (taskB) indicates a sequence relationship that must be followed, while taskA. ShouldRunAfter (taskB) is not required and can be ignored in two cases: The first case is if shouldRunAfter introduces an order loop.
The second case is if all the dependencies of the task are satisfied in parallel execution, then the order is ignored.
Let’s see how it works:
task taskX {
doLast {
println 'flydean.com'
}
}
task taskY {
doLast {
println 'hello'
}
}
taskY.mustRunAfter taskX
//taskY.shouldRunAfter taskX
Copy the code
Give task some description
We can give the task some description so that when we execute Gradle Tasks, we can see:
task copy(type: Copy) {
description 'Copies the resource directory to the target directory.'
from 'resources'
into 'target'
include('**/*.txt'.'**/*.xml'.'**/*.properties')}Copy the code
Conditional execution of task
Sometimes we need to determine whether to execute a particular task based on certain attributes in the build file. We can use onlyIf:
task hello {
doLast {
println 'www.flydean.com'} } hello.onlyIf { ! project.hasProperty('skipHello')}Copy the code
Or we can throw a StopExecutionException, which, if encountered, will not execute subsequent tasks:
task compile {
doLast {
println 'We are doing the compile.'
}
}
compile.doFirst {
if (true) { throw new StopExecutionException() }
}
task myTask {
dependsOn('compile')
doLast {
println 'I am not affected'}}Copy the code
We can also start and disable tasks:
myTask.enabled = false
Copy the code
Finally, we can make the task time out, and when it does, the thread executing the task will be interrupted and the task will be marked failed.
If we want to continue, we can use –continue.
Note that timeout is useful only for tasks that can respond to interrupts.
task hangingTask(a) {
doLast {
Thread.sleep(100000)
}
timeout = Duration.ofMillis(500)}Copy the code
task rule
If we want to define rules for certain tasks, we can use tasks.addrule:
tasks.addRule("Pattern: ping<ID>") { String taskName ->
if (taskName.startsWith("ping")) {
task(taskName) {
doLast {
println "Pinging: " + (taskName - 'ping')}}}}Copy the code
Above we define a rule that will output if the taskName starts with a ping.
Take a look at the results:
> gradle -q pingServer1
Pinging: Server1
Copy the code
I can also introduce these rules as dependencies:
task groupPing {
dependsOn pingServer1, pingServer2
}
Copy the code
Finalizer tasks
Like finally in Java, task can also specify the corresponding Finalize Task:
task taskX {
doLast {
println 'taskX'
}
}
task taskY {
doLast {
println 'taskY'
}
}
taskX.finalizedBy taskY
> gradle -q taskX
taskX
taskY
Copy the code
Finalize Task must be executed, even if taskX above throws an exception.
conclusion
Gradle task is a gradle task.
This article is available at www.flydean.com/gradle-task…
The most popular interpretation, the most profound dry goods, the most concise tutorial, many tips you didn’t know waiting for you to discover!
Welcome to pay attention to my public number: “procedures those things”, understand technology, more understand you!