brief introduction
In the previous article, we talked about how to use gradle to create a simple task, how to rely on tasks, and even use programs to create tasks. In this article, we will learn more about tasks in gradle.
Define task
There are many ways to define a task. For example, the following uses string as the name of the task:
task('hello') { doLast { println "hello" } } task('copy', type: Copy) { from(file('srcDir')) into(buildDir) }
You can also use the tasks container to create:
tasks.create('hello') { doLast { println "hello" } } tasks.create('copy', Copy) { from(file('srcDir')) into(buildDir) }
In the above example, we use tasks The Create method adds the newly created task to the tasks collection.
We can also define a groovy specific syntax:
task(hello) { doLast { println "hello" } } task(copy, type: Copy) { from(file('srcDir')) into(buildDir) }
tasks collection class
When we created the task above, we used the tasks collection class to create the task.
In fact, the tasks collection class is a very useful tool class, and we can use it to do many things.
Using tasks directly in the build file actually refers to an instance object of the TaskContainer. We can also use project Gettasks () to get the instance object.
Let's look at the definition of TaskContainer:
public interface TaskContainer extends TaskCollection<Task>, PolymorphicDomainObjectContainer<Task>
From the definition, we can see that TaskContainer is a collection of tasks and domain objects.
There are four very important methods in taskContainer:
The first type is the method to locate the task. One is findByPath and getByPath respectively. The difference between the two methods is that findByPath will return null if it is not found, while getByPath will throw UnknownTaskException if it is not found.
See how to use:
task hello println tasks.getByPath('hello').path println tasks.getByPath(':hello').path
Output:
:hello :hello
The second type is the Create method of creating a task. The Create method has many implementations. You can create a task directly by name:
task('hello') { doLast { println "hello" } }
You can also create specific types of task s:
task('copy', type: Copy) { from(file('srcDir')) into(buildDir) }
You can also create a task with a constructor with parameters:
class CustomTask extends DefaultTask { final String message final int number [@Inject](https://my.oschina.net/u/4027648) CustomTask(String message, int number) { this.message = message this.number = number } }
We can use this:
tasks.create('myTask', CustomTask, 'hello', 42)
It can also be used as follows:
task myTask(type: CustomTask, constructorArgs: ['hello', 42])
The third type is register, which is also used to create new tasks, but register performs delayed creation. In other words, a task is created only when it is needed.
Let's first look at the definition of a register method:
TaskProvider<Task> register(String name, Action<? super Task> configurationAction) throws InvalidUserDataException
You can see that register returns a TaskProvider, which is a bit like callable in java multithreading. When we call provider The task is created only when get () gets the value of the task.
Or we call taskcollection The corresponding task will also be created when getbyname (Java. Lang. string).
The last type is the replace method:
Task replace(String name) <T extends Task> T replace(String name, Class<T> type)
The function of replace is to create a new task and replace the old task with the same name.
Dependencies between tasks
The dependencies between tasks are determined by task name. We can rely on tasks in the same project:
task hello { doLast { println 'Hello www.flydean.com!' } } task intro { dependsOn hello doLast { println "I'm flydean" } }
You can also make task dependency across projects. If it is a task dependency across projects, you need to formulate the path of the task:
project('project-a') { task taskX { dependsOn ':project-b:taskY' doLast { println 'taskX' } } } project('project-b') { task taskY { doLast { println 'taskY' } } }
Or we can handle the dependencies between tasks after defining tasks:
task taskX { doLast { println 'taskX' } } task taskY { doLast { println 'taskY' } }
You can also dynamically add dependencies:
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' } }
Define the order between task s
Sometimes there is an execution order between our tasks, which is called task ordering.
Let's take a look at the difference between ordering and dependency. Dependency indicates a strong dependency. If taskA depends on taskB, you must execute taskB first when executing taskA.
ordering is a kind of order relation that is not too strong. Indicates that taskA needs to be executed after taskB, but taskB can not be executed.
There are two order s in gradle: must run after and should run after.
taskA.mustRunAfter(taskB) indicates the order relationship that must be followed, while taska Shouldranafter (taskb) is not necessary. In the following two cases, the order relationship can be ignored: the first case is when shouldranafter introduces the order loop.
In the second case, if all the dependencies of the task have been satisfied in the case of parallel execution, this order will also be ignored.
Let's see how to use:
task taskX { doLast { println 'flydean.com' } } task taskY { doLast { println 'hello' } } taskY.mustRunAfter taskX //taskY.shouldRunAfter taskX
Give task some description
We can give some descriptive information to tasks, so that when we execute gradle tasks, we can view:
task copy(type: Copy) { description 'Copies the resource directory to the target directory.' from 'resources' into 'target' include('**/*.txt', '**/*.xml', '**/*.properties') }
Conditional execution of task
Sometimes we need to judge whether to execute a specific task according to some attributes in the build file. We can use onlyIf:
task hello { doLast { println 'www.flydean.com' } } hello.onlyIf { !project.hasProperty('skipHello') }
Or we can throw a StopExecutionException. If this exception is encountered, the tasks following the task will not be executed:
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' } }
We can also start and disable task s:
myTask.enabled = false
Finally, we can make the task timeout. When the timeout occurs, the thread executing the task will be interrupted and the task will be marked as failed.
If we want to continue, we can use -- continue.
Note that a timeout is only useful if it can respond to an interrupted task.
task hangingTask() { doLast { Thread.sleep(100000) } timeout = Duration.ofMillis(500) }
task rule
If we want to define some rules for some tasks, we can use tasks addRule:
tasks.addRule("Pattern: ping<ID>") { String taskName -> if (taskName.startsWith("ping")) { task(taskName) { doLast { println "Pinging: " + (taskName - 'ping') } } } }
On, we defined a rule. If the taskName starts with ping, the corresponding content will be output.
See the operation results:
> gradle -q pingServer1 Pinging: Server1
I can also introduce these rules as dependencies:
task groupPing { dependsOn pingServer1, pingServer2 }
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
finalize task is bound to be executed, even if an exception is thrown in taskX above.
summary
The above is the detailed explanation of task in gradle. I hope you can like it.
This article has been included in http://www.flydean.com/gradle-task-in-depth/
The most popular interpretation, the most profound dry goods, the most concise tutorial, and many tips you don't know are waiting for you to find!
Welcome to my official account: "those things in procedure", understand technology, know you better!