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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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
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
|
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。
1
2
3
|
org.gradle.execution.ExcludedTaskFilteringBuildConfigurationAction @3ee68eb2 index: 0
org.gradle.execution.DefaultTasksBuildExecutionAction @49cd08f9 index: 1
org.gradle.execution.TaskNameResolvingBuildConfigurationAction @4eace42b index: 2
|
他们3个分别处理的事情不一样。
a. ExcludedTaskFilteringBuildConfigurationAction用来处理不执行的task,如果用户有配置的话。
代码如下:
文件路径:
subprojects\core\src\main\java\org\gradle\execution\ExcludedTaskFilteringBuildConfigurationAction.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/**
* 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
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
|
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
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
|
/**
* 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
1
2
3
|
if (gradle.getStartParameter().isConfigureOnDemand()) {
buildListener.projectsEvaluated(gradle);
}
|
到此为止,所有的准备工作都已经做好了,接下就要真正的执行这个task了。
配置文件加载
gradle文件加载以及相应的plugin 类加载
要执行的task选择
下一篇帖子讲task的执行。
本文转自rongwei84n 51CTO博客,原文链接:http://blog.51cto.com/483181/1930223,如需转载请自行联系原作者
17. Gradle编译其他应用代码流程(五) - 设置Task过程相关推荐
- android uefi 编译报错,【Android SDM660开机流程】- UEFI XBL 代码流程分析
[Android SDM660开机流程]- UEFI XBL 代码流程分析 一.UEFI XBL 1.1 boot_images代码目录 1.2 UEFI代码运行流程 1.3 SEC (安全验证) 1 ...
- 全志 android 编译,全志A20启动代码流程分析 ——Android
现在的CPU都固化了内部 ROM,内部 ROM中有一般都有一段程序,一般有如下几个功能: 1,初始化,部分外设,如USB,SDCARD 2,初始化DDR(内存)和NandFlash 3,加载boot( ...
- 全志android 编译,全志A20启动代码流程分析 ——Android
现在的CPU都固化了内部 ROM,内部 ROM中有一般都有一段程序,一般有如下几个功能: 1,初始化,部分外设,如USB,SDCARD 2,初始化DDR(内存)和NandFlash 3,加载boot( ...
- Camera camx代码结构、编译、代码流程简介
文章目录 一.camx 代码结构 二.camx 编译 三.camx 代码流程分析 转载链接: https://juejin.cn/post/6870358276425875463 https://ww ...
- java离线编译_离线代码编译器用吐了,那这五款在线编译器你可以来试试了。...
在云计算时代,使用旧的离线编译器和IDE并不是那么无聊.当然离线是很棒的,但是我们必须在每种系统上手动安装不同的编译器,这需要很大的空间,而且要将代码移植到多个系统上也不容易.但是使用在线编译器或ID ...
- 【错误记录】Android Studio 中编写 Gradle 编译脚本时没有 Groovy 代码提示 ( Cannot find declaration to go to )
文章目录 一.报错信息 二.解决方案 一.报错信息 在 Android Studio 工程中 , 编辑 build.gradle 脚本时 , 无法进行代码提示 ; 按住 Ctrl 键 , 点击相应的属 ...
- 3-uboot-spl代码流程
[uboot] (第三章)uboot流程--uboot-spl代码流程 2016年10月28日 16:24:14 阅读数:2077 以下例子都以project X项目tiny210(s5pv210平台 ...
- gradle编译打包过程 之 ProcessAndroidResources的源码分析
首先,如何查看gradle源码,我们在项目里依赖com.android.tools.build:gradle即可,如下: compile gradleApi() compile 'com.androi ...
- apt 根据注解,编译时生成代码
apt: @Retention后面的值,设置的为CLASS,说明就是编译时动态处理的.一般这类注解会在编译的时候,根据注解标识,动态生成一些类或者生成一些xml都可以,在运行时期,这类注解是没有的~~ ...
最新文章
- 神舟台式计算机图片,扩展性媲美台式机!神舟战神K780G拆机图赏
- 用类模拟C风格的赋值+返回值
- 软件项目经理需具备什么样的技术水平?
- java中读取某路径下的文本内容
- jquery知识巩固
- java etcd api_在java中如何使用etcd的v2 和v3 api获取配置,并且对配置的变化进行监控和监听...
- Postgresql添加/删除触发器示例
- CentOS7安装Gnome GUI图形界面
- C#关于委托(基础)
- python交互式程序设计导论小测验答案_最新网课答案2021学堂在线Python 交互式程序设计导论...
- 考研数学(二)知识点回顾及笔记(第五章 定积分及应用)
- 精益生产管理专家——安岷老师
- 360网上商城:链接生态与终端
- 爬虫-爬取中国诗歌网中中国好诗栏目 - 统计词汇出现频数 - 副本
- Export encrypted key
- 女孩子适合软件测试这个行业吗?【工作内容、薪资、加班、怎么转行、职业规划】全面解析女生适不适合软件测试。
- 社区说 | Flutter 工程那些事儿
- C语言_回文字符串的判断
- 美橙互联短信服务——发送注册短信并验证
- 济南近郊出游——线路指南
热门文章
- spirng底层实现原理
- 'int' object has no attribute 'backward'报错 使用Pytorch编写 Hinge loss函数
- mysql datasource.url_SpringBoot配置数据源DataSource
- 单击选定单元格后输入新内容_2015年计算机一级msoffice考前简答题练习
- IntObjectHashMap和HashMap的区别?
- [Ext JS 4] 实战之Chart, Column Chart 定制颜色
- Teamcenter - Index search 找不到相关物件的解决方法
- android动态调试防止,Android应用防止so注入防止动态调试参考代码
- MATLAB图像处理之图像边缘提取
- huffman算法c语言程序,哈夫曼算法构造代码