Foreword
In this article, we talk Gradle
about another important conceptTask
1. Task
Definition and configuration
1.1 Task
Definition
The first: can be directly task
defined by the function
The second kind: the TaskContainer
is the one we circled with a red frame above, how to create it? Just call the create
method directly
What is the difference between these two methods? In fact, the first method will eventually be added to TaskContainer
it, which is TaskContainer
equivalent to our Task
management class.Since it is a management class, it can be created not only, let us look at its source code
@HasInternalProtocol
public interface TaskContainer extends TaskCollection<Task>, PolymorphicDomainObjectContainer<Task> {
...
@Nullable
Task findByPath(String path);
Task getByPath(String path) throws UnknownTaskException;
<T extends Task> T create(String name, Class<T> type, Action<? super T> configuration) throws InvalidUserDataException;
TaskProvider<Task> register(String name, Action<? super Task> configurationAction) throws InvalidUserDataException;
Task replace(String name);
...
After reading the source code, we found that it is TaskContainer
mainly to find and add, and we rarely use other
1.2 Task
Configuration
For example, we want to task
configure the group name and description for our
The first type: we directly configure it when it is defined.
The second type: call various configuration methods in the configuration code block
The same groupings task
will be put together. Let ’s see
what we can task
configure? Let ’s go to the Task
source code and see.
2. Task
Detailed execution
We found that when we execute helloTask
this task
, it will also print out helloTask2
the output content. Why? It is very simple, because they are executed in the configuration phase, so how do we make them execute in the execution phase? Call doFirst
or doLast
method
Let us see the result
First doFirst
and doLast
really executed in the execution stage is then performed on the outside doFirst
or doLast
to take precedence over the closure, the two methods can gradle
provided already task
extended
Below we will count our build
time under actual combat
:
- 1. Define two variables: start execution time and execution end time, the difference between the two is the result we want
- 2. Find the first one to be executed
task
, call thedoFirst
method and get the start time - 3. Find the last executed
task
, executedoLast
method, get the end time - 4. The difference between the two.
We print to see how long it will take
3. Task
Dependency and execution order
3.1 Task
Dependence
We first define three. task
We first execute nothing and taskC
only output it taskC
. We will compare it with this later . What do
we want to do for our taskC
specified dependency?
The first one: add at the time of definition
dependsOn
, just like we addedgroup
before
Add multiple need to use the array
we executetaskC
The second: call
dependsOn
method
The third: dynamic dependence
Here we will create a few more for demonstrationtask
Then we used TaskContainer
the findAll
method to find me in line with ours task
, and then taskC
rely on them
We executetaskC
3.2 Task
input and output
TaskInputs
: The Task
input class can be any data type and file
TaskOutputs
: The Task
output class can only be a file or folder, and it can also be used as another Task
. TaskInputs
Below we write a small example to learn these two methods.
Suppose we want to output a xml
file. The content includes the version number and version information.First of
all, we create three extended attributes:
here we also need to define one File
, which is ours release.xml
, if it does not exist, we manually create it
Then we started to implement our read and write functions. Correspondingly, we need to create two task
, writeTask
and readTask
we write first . We need writeTask
to pass the three attributes we defined earlier to ourtask
inputs.property('versionCode', this.versionCode)
inputs.property('versionName', this.versionName)
inputs.property('versionInfo', this.versionInfo)
Also specify the output
//为task指定输出
outputs.file this.destFile
Here's start writing real logic, this logic written doLast{}
in
task writeTask {
inputs.property('versionCode', this.versionCode)
inputs.property('versionName', this.versionName)
inputs.property('versionInfo', this.versionInfo)
outputs.file this.destFile
doLast {
// 返回一个map
def data = inputs.getProperties()
File file = outputs.getFiles().getSingleFile()
// 将map转为实体对象
def versionMsg = new VersionMsg(data)
def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw)
// 文件中没有内容
if (file.text != null && file.text.size() <= 0) {
// 将xml数据写入到sw中
xmlBuilder.releases { // <releases>
release { // <releases>的子节点<release>
versionCode(versionMsg.versionCode)
// <release>的子节点<versionCode>1.0.0<versionCode>
versionName(versionMsg.versionName)
versionInfo(versionMsg.versionInfo)
}
}
// 将sw里的内容写到文件中
file.withWriter { writer ->
writer.append(sw.toString())
}
} else { // 已经有其它版本信息了
xmlBuilder.release {
versionCode(versionMsg.versionCode)
versionName(versionMsg.versionName)
versionInfo(versionMsg.versionInfo)
}
def lines = file.readLines()
def lengths = lines.size() - 1
file.withWriter { writer ->
lines.eachWithIndex { String line, int index ->
if (index != lengths) {
writer.append(line + '\r\n')
} else if (index == lengths) {
writer.append(sw.toString() + '\r\n')
writer.append(line + '\r\n')
}
}
}
}
}
}
task readTask {
inputs.file destFile
doLast {
def file = inputs.files.singleFile
println file.text
}
}
Then write a test that task
depends on these twotask
task taskTest(dependsOn: [writeTask, readTask]) {
doLast {
println '任务执行完毕'
}
}
Here is a place to note, the writeTask
order of execution is a priority in readTask
the
3.3 Task
By API
specifying the execution order
mustRunAfter
: Forced toask
execute after one or some t is executed.shouldRunAfter
: SamemustRunAfter
as the function, but not mandatory.
Here we create a few task
to practice
Here we enforce the order taskX
, taskY
, taskZ
the order of the output to the next we look upset
4. Attach to the build life cycle
This is similar to what we explained before to get the build time. Here we execute our custom project after the project is built.task
5. Task
Type of
This we need to go to gradle
the official website to get to know at the
official website
open official website, found on the left sideTask types
Like we said beforeCopy