1. foreword

When we use Gradle to build tasks, we sometimes want to count the time consumption of each task, so as to find out the running time of each task and whether there is room for optimization.

train of thought
1.Custom Gradle plugins
2.Use Listener to monitor
3.Register Listener in custom Gradle plugin

Gradle provides many build lifecycle hook functions

  1. We can use TaskExecutionListener to monitor the execution of tasks throughout the build process:
1
2
3
4
5
6
7
8

public interface TaskExecutionListener {

void beforeExecute(Task var1);

void afterExecute(Task var1, TaskState var2);
}

We can collect information before each task execution, record the start time of the task execution, and record the execution end time after the task execution is completed, so that we can count the execution time of the task.

  1. Use BuildListener to monitor whether the entire build is complete. After the build is complete, output all executed task information and the execution time of each task
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.gradle;  

import org.gradle.api.Incubating;
import org.gradle.api.initialization.Settings;
import org.gradle.api.invocation.Gradle;

public interface BuildListener {

void buildStarted(Gradle var1);

@Incubating
default void beforeSettings(Settings settings) {
}

void settingsEvaluated(Settings var1);

void projectsLoaded(Gradle var1);

void projectsEvaluated(Gradle var1);

void buildFinished(BuildResult var1);
}

In the buildFinished method, monitor the completion and success of the build, and print the time-consuming information we collected.

2.code implementation

  1. Create main project

    Create the main project TaskBuildTimeDemo, there is only one MainActivity in the current project, as follows:

    1

  2. Custom Gradle plugins

    First create a new module in the TaskBuildTimeDemo project, select the Android Library type, and name it task_build_time_plugin。

Configure the plug-in environment, delete all the contents of the build.gradle of the task_build_time_plugin module, and change it to the following:

12

Because the Gradle plug-in is written in the groovy language, it is necessary to create a new groovy directory to store the .groovy classes related to the plug-in. The structure is as follows

2

Then, create a directory com.example.task_build_time_plugin in groovy and create a class TaskBuildTimePlugin.groovy file in this directory. Rewrite the apply method in TaskBuildTimePlugin to implement the plug-in logic, first simply print a log log to see the effect

3

Next, register the plug-in, create a new resources/META-INF/gradle-plugins directory under main, and create a com.example.taskbuildtime.properties file. This file name is the name referenced by other modules when passing the apply plugin. The content in it specifies the plug-in class full class name

4

Publish the plugin to the local warehouse, because we referenced the maven-publish plugin, double-click publish to publish to the specified local warehouse path

5

Go to the specified local warehouse to see if the corresponding plugin is generated

6

test plugin

Depend on the plugin in the outermost build.gradle of the project

7

Then import the plugin in the corresponding module

8

Execute the assemble Debug command of gradle, if the log in the plug-in class is printed out, it means that the custom plug-in is successful

9

  1. Task time-consuming tool class implementation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.example.task_build_time_plugin  

import org.gradle.BuildListener
import org.gradle.BuildResult
import org.gradle.api.Task
import org.gradle.api.execution.TaskExecutionListener
import org.gradle.api.initialization.Settings
import org.gradle.api.invocation.Gradle
import org.gradle.api.tasks.TaskState

class BuildTimeListener implements TaskExecutionListener, BuildListener {

// Used to record the execution time information of the task
Map<String, TaskTimeInfo> taskTimeMap = new HashMap<>()

@Override
void buildStarted(Gradle gradle) {

}

@Override
void beforeSettings(Settings settings) {
super.beforeSettings(settings)
}

@Override
void settingsEvaluated(Settings settings) {

}

@Override
void projectsLoaded(Gradle gradle) {

}

@Override
void projectsEvaluated(Gradle gradle) {

}

@Override
void buildFinished(BuildResult buildResult) {
println "-------build finished, now println all task execution time-------"
taskTimeMap.each { k, v -> println "${k}:[${v.total}ms]" }
println "-----------------------------------------------------------------"
}

@Override
void beforeExecute(Task task) {
// Collect task information before the task starts executing
TaskTimeInfo timeInfo = new TaskTimeInfo()
timeInfo.start = System.currentTimeMillis()
timeInfo.path = task.getPath()
taskTimeMap.put(task.getPath(), timeInfo)
}

@Override
void afterExecute(Task task, TaskState taskState) {
// After the task is executed, the time when the record ends
TaskTimeInfo timeInfo = taskTimeMap.get(task.getPath())
timeInfo.end = System.currentTimeMillis()
// Calculate the execution time of the task
timeInfo.total = timeInfo.end - timeInfo.start
}

class TaskTimeInfo {
long total
String path
long start
long end
}
}

Register the task time-consuming monitoring tool class in the plug-in

10

Task time-consuming statistical results

11

So far, the custom Gradle plug-in to realize the time-consuming function of statistical tasks has been basically completed. We can find out the time-consuming tasks and see if there is room for optimization, so as to improve the efficiency of packaging