From d1323942477bbb315d69f90900cc8bad150b51f6 Mon Sep 17 00:00:00 2001 From: yangchong Date: Thu, 31 Mar 2022 19:02:04 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=9F=E8=AE=A1Task=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E5=AD=A6=E4=B9=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AptHelper/BuildTimeCostPlugin/.gitignore | 1 + AptHelper/BuildTimeCostPlugin/build.gradle | 24 ++++ .../loader/gradle/BuildTimeCostPlugin.java | 109 ++++++++++++++++++ .../loader/gradle/task/AppBuildListener.java | 37 ++++++ .../gradle/task/AppTaskExecutionListener.java | 22 ++++ .../gradle/task/BuildTimeCostExtension.java | 26 +++++ .../loader/gradle/task/TaskExecTimeInfo.java | 52 +++++++++ .../com.yc.time.loader.properties | 4 + .../com.yc.spi.loader.properties | 2 +- settings.gradle | 3 +- 10 files changed, 278 insertions(+), 2 deletions(-) create mode 100644 AptHelper/BuildTimeCostPlugin/.gitignore create mode 100644 AptHelper/BuildTimeCostPlugin/build.gradle create mode 100644 AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/BuildTimeCostPlugin.java create mode 100644 AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/AppBuildListener.java create mode 100644 AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/AppTaskExecutionListener.java create mode 100644 AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/BuildTimeCostExtension.java create mode 100644 AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/TaskExecTimeInfo.java create mode 100644 AptHelper/BuildTimeCostPlugin/src/main/resources/META-INF/gradle-plugins/com.yc.time.loader.properties diff --git a/AptHelper/BuildTimeCostPlugin/.gitignore b/AptHelper/BuildTimeCostPlugin/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/AptHelper/BuildTimeCostPlugin/.gitignore @@ -0,0 +1 @@ +/build diff --git a/AptHelper/BuildTimeCostPlugin/build.gradle b/AptHelper/BuildTimeCostPlugin/build.gradle new file mode 100644 index 000000000..3e3c3117a --- /dev/null +++ b/AptHelper/BuildTimeCostPlugin/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'java' +apply plugin: 'groovy' +apply plugin: 'com.github.dcendents.android-maven' + + +sourceCompatibility = "1.8" +targetCompatibility = "1.8" + +repositories { + mavenLocal() + mavenCentral() + jcenter() +} + +dependencies { + implementation gradleApi() + implementation localGroovy() + implementation 'org.javassist:javassist:3.18.2-GA' + implementation 'com.squareup:javapoet:1.7.0' + implementation 'com.android.tools.build:gradle:3.0.0' + implementation project(path: ':ServiceLoaderApi') + implementation project(':ServiceLoaderAnnotations') +} + diff --git a/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/BuildTimeCostPlugin.java b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/BuildTimeCostPlugin.java new file mode 100644 index 000000000..f7ce5ad81 --- /dev/null +++ b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/BuildTimeCostPlugin.java @@ -0,0 +1,109 @@ +package com.yc.time.loader.gradle; + + +import com.yc.time.loader.gradle.task.AppBuildListener; +import com.yc.time.loader.gradle.task.AppTaskExecutionListener; +import com.yc.time.loader.gradle.task.BuildTimeCostExtension; +import com.yc.time.loader.gradle.task.TaskExecTimeInfo; +import org.gradle.BuildResult; +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.Task; +import org.gradle.api.tasks.TaskState; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +public class BuildTimeCostPlugin implements Plugin { + + //用来记录 task 的执行时长等信息 + Map timeCostMap = new HashMap<>(); + //用来按顺序记录执行的 task 名称 + List taskPathList = new ArrayList<>(); + + @Override + @SuppressWarnings("deprecation") + public void apply(final Project project) { + // 监听每个task的执行 + // 在每个 task 执行前先搜集其相关信息,记录该 task 执行的开始时间等, + // 在 task 执行完成后,记录其执行结束时间,这样就能统计出该 task 的执行时长。 + project.getGradle().addListener(new AppTaskExecutionListener() { + @Override + public void beforeExecute(Task task) { + //task开始执行之前搜集task的信息 + TaskExecTimeInfo timeInfo = new TaskExecTimeInfo(); + //记录开始时间 + timeInfo.setStart(System.currentTimeMillis()); + timeInfo.setPath(task.getPath()); + timeCostMap.put(task.getPath(), timeInfo); + taskPathList.add(task.getPath()); + } + + @Override + public void afterExecute(Task task, TaskState taskState) { + //task执行完之后,记录结束时的时间 + TaskExecTimeInfo timeInfo = timeCostMap.get(task.getPath()); + //记录结束时间 + timeInfo.setEnd(System.currentTimeMillis()); + //计算该 task 的执行时长 + timeInfo.setTotal(timeInfo.getEnd() - timeInfo.getStart()); + } + }); + + //创建一个 Extension,配置输出结果 + final BuildTimeCostExtension timeCostExt = project.getExtensions().create( + "taskExecTime", BuildTimeCostExtension.class); + //编译结束之后: + project.getGradle().addBuildListener(new AppBuildListener() { + @Override + public void buildFinished(@NotNull BuildResult buildResult) { + log("build finished, now println all task execution time:"); + //按 task 执行顺序打印出执行时长信息 + if (timeCostExt.isSorted()){ + //进行排序 + List list = new ArrayList<>(); + Set keySet = timeCostMap.keySet(); + Iterator iterator = keySet.iterator(); + while (iterator.hasNext()){ + String key = iterator.next(); + TaskExecTimeInfo taskExecTimeInfo = timeCostMap.get(key); + list.add(taskExecTimeInfo); + } + Collections.sort(list, new Comparator() { + @Override + public int compare(TaskExecTimeInfo t1, TaskExecTimeInfo t2) { + return (int) (t2.getTotal() - t1.getTotal()); + } + }); + for (TaskExecTimeInfo timeInfo : list) { + long t = timeInfo.getTotal(); + if (t >= timeCostExt.getThreshold()) { + log(timeInfo.getPath() + " " + t + "ms"); + } + } + } else { + for (String path : taskPathList) { + long t = timeCostMap.get(path).getTotal(); + if (t >= timeCostExt.getThreshold()) { + log(path + " " + t + "ms"); + } + } + } + log("build finished, time all print , yc"); + } + }); + } + + public static void log(String string){ + System.out.print("task time log : " + string); + } + +} diff --git a/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/AppBuildListener.java b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/AppBuildListener.java new file mode 100644 index 000000000..01b5a3338 --- /dev/null +++ b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/AppBuildListener.java @@ -0,0 +1,37 @@ +package com.yc.time.loader.gradle.task; + +import org.gradle.BuildListener; +import org.gradle.BuildResult; +import org.gradle.api.initialization.Settings; +import org.gradle.api.invocation.Gradle; +import org.jetbrains.annotations.NotNull; + +/** + * 可以用 BuildListener 来监听整个构建是否完成,在构建完成后,输出所有执行过的 task 信息,以及每个 task 的执行时长 + */ +public class AppBuildListener implements BuildListener { + @Override + public void buildStarted(@NotNull Gradle gradle) { + + } + + @Override + public void settingsEvaluated(@NotNull Settings settings) { + + } + + @Override + public void projectsLoaded(@NotNull Gradle gradle) { + + } + + @Override + public void projectsEvaluated(@NotNull Gradle gradle) { + + } + + @Override + public void buildFinished(@NotNull BuildResult buildResult) { + + } +} diff --git a/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/AppTaskExecutionListener.java b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/AppTaskExecutionListener.java new file mode 100644 index 000000000..91989d070 --- /dev/null +++ b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/AppTaskExecutionListener.java @@ -0,0 +1,22 @@ +package com.yc.time.loader.gradle.task; + +import org.gradle.api.Task; +import org.gradle.api.execution.TaskExecutionListener; +import org.gradle.api.tasks.TaskState; +import org.jetbrains.annotations.NotNull; + + +/** + * Gradle 提供了很多构建生命周期钩子函数,我们可以用 TaskExecutionListener 来监听整个构建过程中 task 的执行 + */ +public class AppTaskExecutionListener implements TaskExecutionListener { + @Override + public void beforeExecute(@NotNull Task task) { + + } + + @Override + public void afterExecute(@NotNull Task task, @NotNull TaskState taskState) { + + } +} diff --git a/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/BuildTimeCostExtension.java b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/BuildTimeCostExtension.java new file mode 100644 index 000000000..c02d06487 --- /dev/null +++ b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/BuildTimeCostExtension.java @@ -0,0 +1,26 @@ +package com.yc.time.loader.gradle.task; + +public class BuildTimeCostExtension { + + //task执行时间超过该值才会统计 + private int threshold; + + //是否按照task执行时长进行排序,true-表示从大到小进行排序,false-表示不排序 + private boolean sorted; + + public void threshold(int threshold) { + this.threshold = threshold; + } + + public void sorted(boolean sorted) { + this.sorted = sorted; + } + + public int getThreshold() { + return threshold; + } + + public boolean isSorted() { + return sorted; + } +} diff --git a/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/TaskExecTimeInfo.java b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/TaskExecTimeInfo.java new file mode 100644 index 000000000..f62d3b07b --- /dev/null +++ b/AptHelper/BuildTimeCostPlugin/src/main/java/com/yc/time/loader/gradle/task/TaskExecTimeInfo.java @@ -0,0 +1,52 @@ +package com.yc.time.loader.gradle.task; + +public final class TaskExecTimeInfo { + /** + * task执行总时长 + */ + private long total; + /** + * task 路径 + */ + private String path; + /** + * task 执行开始时间 + */ + private long start; + /** + * task 结束时间 + */ + private long end; + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public long getStart() { + return start; + } + + public void setStart(long start) { + this.start = start; + } + + public long getEnd() { + return end; + } + + public void setEnd(long end) { + this.end = end; + } +} diff --git a/AptHelper/BuildTimeCostPlugin/src/main/resources/META-INF/gradle-plugins/com.yc.time.loader.properties b/AptHelper/BuildTimeCostPlugin/src/main/resources/META-INF/gradle-plugins/com.yc.time.loader.properties new file mode 100644 index 000000000..97c9fdff9 --- /dev/null +++ b/AptHelper/BuildTimeCostPlugin/src/main/resources/META-INF/gradle-plugins/com.yc.time.loader.properties @@ -0,0 +1,4 @@ +# resources目录会被自动识别为资源文件夹 +# resources目录下新建文件夹META-INF,META-INF文件夹下新建gradle-plugins文件夹 +# plugin的全路径地址,注意该文件的命名就是你之后使用插件的名字 +implementation-class=com.yc.time.loader.gradle.BuildTimeCostPlugin diff --git a/AptHelper/ServiceLoaderPlugin/src/main/resources/META-INF/gradle-plugins/com.yc.spi.loader.properties b/AptHelper/ServiceLoaderPlugin/src/main/resources/META-INF/gradle-plugins/com.yc.spi.loader.properties index da4955a91..cfb7311c4 100644 --- a/AptHelper/ServiceLoaderPlugin/src/main/resources/META-INF/gradle-plugins/com.yc.spi.loader.properties +++ b/AptHelper/ServiceLoaderPlugin/src/main/resources/META-INF/gradle-plugins/com.yc.spi.loader.properties @@ -1,4 +1,4 @@ # resources目录会被自动识别为资源文件夹 # resources目录下新建文件夹META-INF,META-INF文件夹下新建gradle-plugins文件夹 # plugin的全路径地址,注意该文件的命名就是你之后使用插件的名字 -implementation-class=com.yc.spi.loader.gradle.ServiceLoaderPlugin +implementation-class=com.yc.spi.loader.gradle.BuildTimeCostPlugin diff --git a/settings.gradle b/settings.gradle index eb0ab225b..97145569b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -92,12 +92,13 @@ project(':AutoCloserLib').projectDir = new File('ToolLib/AutoCloserLib') /* +++++++++ Apt框架基础工具库 +++++++++ */ -include ':RouteCompiler', ':RouteManager', ':RouteAnnotations', +include ':RouteCompiler', ':RouteManager', ':RouteAnnotations',':BuildTimeCostPlugin', ':ServiceLoaderApi', ':ServiceLoaderAnnotations', ':ServiceLoaderRegistry', ':ServiceLoaderPlugin', ':ServiceLoaderProcessor' project(':RouteCompiler').projectDir = new File('AptHelper/RouteCompiler') project(':RouteManager').projectDir = new File('AptHelper/RouteManager') project(':RouteAnnotations').projectDir = new File('AptHelper/RouteAnnotations') +project(':BuildTimeCostPlugin').projectDir = new File('AptHelper/BuildTimeCostPlugin') project(':ServiceLoaderApi').projectDir = new File('AptHelper/ServiceLoaderApi') project(':ServiceLoaderAnnotations').projectDir = new File('AptHelper/ServiceLoaderAnnotations') project(':ServiceLoaderRegistry').projectDir = new File('AptHelper/ServiceLoaderRegistry')