17. Gradle编译其他应用代码流程(五) - 设置Task过程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了17. Gradle编译其他应用代码流程(五) - 设置Task过程相关的知识,希望对你有一定的参考价值。
接上一篇 15. Gradle编译其他应用代码流程(四) - Configure过程 继续分析
一. task选择
到了这个阶段,gradle开始计算task入口是哪个? 选择的逻辑是这样:
如果用户收入了task,比如这样的指令‘gradle pmd‘,那么就执行pmd这个task
如果用户没有输入task,比如直接输入‘gradle‘,那么看有没有默认的task
如果没有默认的task,那就执行help这个task。大家可以试下直接输入gradle,看看输出什么内容。
接下来看源代码。
文件路径:subprojects\core\src\main\java\org\gradle\initialization\DefaultGradleLauncher.java
private void doBuildStages(Stage upTo) { ... // After this point, the GradleLauncher cannot be reused stage = Stage.Build; // Populate task graph buildOperationExecutor.run("Calculate task graph", new Runnable() { @Override public void run() { buildConfigurationActionExecuter.select(gradle); if (gradle.getStartParameter().isConfigureOnDemand()) { buildListener.projectsEvaluated(gradle); } } }); ... }
文件路径:
subprojects\core\src\main\java\org\gradle\execution\DefaultBuildConfigurationActionExecuter.java
public class DefaultBuildConfigurationActionExecuter implements BuildConfigurationActionExecuter { ... public void select(GradleInternal gradle) { List<BuildConfigurationAction> processingBuildActions = CollectionUtils.flattenCollections(BuildConfigurationAction.class, configurationActions, taskSelectors); configure(processingBuildActions, gradle, 0); } ... private void configure(final List<BuildConfigurationAction> processingConfigurationActions, final GradleInternal gradle, final int index) { if (index >= processingConfigurationActions.size()) { return; } BuildConfigurationAction action = processingConfigurationActions.get(index); System.out.println("DefaultBuildConfigurationActionExecuter action: " + action + " index: " + index); /*processingConfigurationActions.get(index)*/action.configure(new BuildExecutionContext() { public GradleInternal getGradle() { return gradle; } public void proceed() { configure(processingConfigurationActions, gradle, index + 1); } }); } }
这个地方的写法挺奇怪的,它的想法是遍历processingConfigurationActions里面的每个action,然后执行它的configure方法,所以它用了递归。
但是个人觉得直接用循环不是更简单直接吗?
先不去管这些,processingConfigurationActions里面有3个成员,他们继承自同一接口BuildConfigurationAction。
org[email protected]3ee68eb2 index: 0 [email protected] index: 1 [email protected]eace42b index: 2
他们3个分别处理的事情不一样。
a. ExcludedTaskFilteringBuildConfigurationAction用来处理不执行的task,如果用户有配置的话。
代码如下:
文件路径:
subprojects\core\src\main\java\org\gradle\execution\ExcludedTaskFilteringBuildConfigurationAction.java
/** * A {@link BuildConfigurationAction} which filters excluded tasks. */ public class ExcludedTaskFilteringBuildConfigurationAction implements BuildConfigurationAction { ... public void configure(BuildExecutionContext context) { GradleInternal gradle = context.getGradle(); Set<String> excludedTaskNames = gradle.getStartParameter().getExcludedTaskNames(); if (!excludedTaskNames.isEmpty()) { final Set<Spec<Task>> filters = new HashSet<Spec<Task>>(); for (String taskName : excludedTaskNames) { filters.add(taskSelector.getFilter(taskName)); } gradle.getTaskGraph().useFilter(Specs.intersect(filters)); } context.proceed(); } }
b. DefaultTasksBuildExecutionAction用来处理默认的task,如果用户有输入task,那么就使用用户输入的。比如用户输入‘gradle pmd‘,那么使用的task就是pmd
如果用户没有输入task,那么就使用默认的task
如果默认task也没有,则使用help task,比如用户直接输入‘gradle‘
文件路径:
subprojects\core\src\main\java\org\gradle\execution\DefaultTasksBuildExecutionAction.java
public class DefaultTasksBuildExecutionAction implements BuildConfigurationAction { ... public void configure(BuildExecutionContext context) { StartParameter startParameter = context.getGradle().getStartParameter(); System.out.println("DefaultTasksBuildExecutionAction configure. startParameter: " + startParameter); //判断是否有输入task? for (TaskExecutionRequest request : startParameter.getTaskRequests()) { if (!request.getArgs().isEmpty()) { context.proceed(); return; } } //没有输入task,尝试使用默认task和help task // Gather the default tasks from this first group project ProjectInternal project = context.getGradle().getDefaultProject(); //so that we don‘t miss out default tasks projectConfigurer.configure(project); List<String> defaultTasks = project.getDefaultTasks(); if (defaultTasks.size() == 0) { defaultTasks = Collections.singletonList(ProjectInternal.HELP_TASK); LOGGER.info("No tasks specified. Using default task {}", GUtil.toString(defaultTasks)); System.out.println("No tasks specified. Using default task {}" + "-" + GUtil.toString(defaultTasks)); } else { LOGGER.info("No tasks specified. Using project default tasks {}", GUtil.toString(defaultTasks)); System.out.println("No tasks specified. Using project default tasks {}" + " - " + GUtil.toString(defaultTasks)); } startParameter.setTaskNames(defaultTasks); context.proceed(); } }
c. TaskNameResolvingBuildConfigurationAction
把输入的task(如果没有输入,则使用默认task或者 help)添加到executer里面,为真正执行做准备。
代码路径:
subprojects\core\src\main\java\org\gradle\execution\TaskNameResolvingBuildConfigurationAction.java
/** * A {@link BuildConfigurationAction} which selects tasks which match the provided names. For each name, selects all tasks in all * projects whose name is the given name. */ public class TaskNameResolvingBuildConfigurationAction implements BuildConfigurationAction { ... public void configure(BuildExecutionContext context) { System.out.println("TaskNameResolvingBuildConfigurationAction configure 1"); GradleInternal gradle = context.getGradle(); TaskGraphExecuter executer = gradle.getTaskGraph(); List<TaskExecutionRequest> taskParameters = gradle.getStartParameter().getTaskRequests(); for (TaskExecutionRequest taskParameter : taskParameters) { System.out.println("TaskNameResolvingBuildConfigurationAction configure 2"); List<TaskSelector.TaskSelection> taskSelections = commandLineTaskParser.parseTasks(taskParameter); for (TaskSelector.TaskSelection taskSelection : taskSelections) { LOGGER.info("Selected primary task ‘{}‘ from project {}", taskSelection.getTaskName(), taskSelection.getProjectPath()); System.out.println("Selected primary task ‘{}‘ from project {}" + taskSelection.getTaskName() + "-"+ taskSelection.getProjectPath()); executer.addTasks(taskSelection.getTasks()); } } context.proceed(); } }
二. 通知projectsEvaluated
if (gradle.getStartParameter().isConfigureOnDemand()) { buildListener.projectsEvaluated(gradle); }
到此为止,所有的准备工作都已经做好了,接下就要真正的执行这个task了。
配置文件加载
gradle文件加载以及相应的plugin 类加载
要执行的task选择
下一篇帖子讲task的执行。
本文出自 “www.bogo.com” 博客,请务必保留此出处http://483181.blog.51cto.com/473181/1930223
以上是关于17. Gradle编译其他应用代码流程(五) - 设置Task过程的主要内容,如果未能解决你的问题,请参考以下文章
Android Gradle安卓应用构建流程 ( 资源文件编译 )
Android Gradle安卓应用构建流程 ( Java 源码编译 和 AIDL 文件编译 )