Gradle学习系列(六):Gradle 源码解析

概述

又开始了一个新的系列,这个系列学习Gradle,目标就是彻底理解Gradle,主要还是做下自己理解的笔记,防止忘记

Gradle系列(一):Groovy学习

Gradle学习系列(二):Gradle核心解密

Gradle学习系列(三):Gradle插件

Gradle学习系列(四):Gradle依赖

Gradle学习系列(五):Gradle Transform

Gradle学习系列(六):Gradle 源码解析

Gradle 源码解析

gradlew

首先我们平时打包时用的命令 ./gradlew assembleDebug ,其中的gradlew就是Gradle的入口

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

这个命令触发了GradleWrapperMain,他还支持$@传递参数,我们平时使用的gradlew命令都是这样运行的

下面看一下GradleWrapperMain

GradleWrapperMain

public class GradleWrapperMain {
    
    
    //执行gradlew脚本命令触发的入口
    public static void main(String[] args) throws Exception {
    
    
        //这个就是获取工程目录下的wrapper.jar 和 properties 文件
        File wrapperJar = wrapperJar();
        File propertiesFile = wrapperProperties(wrapperJar);
        File rootDir = rootDir(wrapperJar);
        ...
        //下边这俩行是最重要的俩行
        WrapperExecutor wrapperExecutor = WrapperExecutor.forWrapperPropertiesFile(propertiesFile);

        wrapperExecutor.execute(
            args, 
            new Install(logger, 
            new Download(logger, "gradlew", wrapperVersion()), new PathAssembler(gradleUserHome)),
            new BootstrapMainStarter());
    }

WrapperExecutor.forWrapperPropertiesFile就是通过java Properties去解析gradle/wrapper/gradle-wrapper.properties文件,比如distributionUrl

wrapperExecutor.execute其中args就是我们执行gradlew中的参数,Install就是管理本地项目是否有wrapper指定的gradle版本,木有就去解析下载,BootstrapMainStarter就是wrapper执行gradle的真实入口,下面继续看一下execute方法

public void execute(String[] args, Install install, BootstrapMainStarter bootstrapMainStarter) throws Exception {
    
    
    //config 就是 gradle-wrapper.properties 解析的配置
    File gradleHome = install.createDist(config);
    bootstrapMainStarter.start(args, gradleHome);
}

install.createDist(config)这个主要做的就是下载gradle wrappe所需要的依赖和源码,其中下载的版本就是gradle/wrapper/gradle-wrapper.properties 里配置的 distributionUrl,下载的地址就是gradle-wrapper.properties 中配置的distributionPath 和 zipStorePath,zipStorePath是下载压缩包的位置,distributionPath就是解压后的位置

Gradle构建包括以下5个流程,这个流程的枚举

  private static enum Stage {
    
    
        LoadSettings,
        Configure,
        TaskGraph,
        RunTasks {
    
    
            String getDisplayName() {
    
    
                return "Build";
            }
        },
        Finished;

        private Stage() {
    
    
        }

        String getDisplayName() {
    
    
            return this.name();
        }
    }

Gradle构建一共经历了5个流程,下面我们依次分析一下这几个流程

一.LoadSettings

loadSettings 主要是加载 settings.gradle 文件,然后创建对应的 project。

bootstrapMainStarter.start作用是开始执行gradle的构建流程,经过复杂的调用过程,最终会触发DefaultGradleLauncher.executeTasks()方法,我们看下这个方法

 public GradleInternal executeTasks() {
    
    
        this.doBuildStages(DefaultGradleLauncher.Stage.RunTasks);
        return this.gradle;
    }

调用了doBuildStages方法

 private void doBuildStages(DefaultGradleLauncher.Stage upTo) {
    
    
        //首先判断状态不是Finish
        Preconditions.checkArgument(upTo != DefaultGradleLauncher.Stage.Finished, "Stage.Finished is not supported by doBuildStages.");

        try {
    
    
            
            if (upTo == DefaultGradleLauncher.Stage.RunTasks && this.instantExecution.canExecuteInstantaneously()) {
    
    
                //如果状态是RunTasks,就执行这个方法
                this.doInstantExecution();
            } else {
    
    
                //不是RunTasks就执行下面
                this.doClassicBuildStages(upTo);
            }
        } catch (Throwable var3) {
    
    
            this.finishBuild(upTo.getDisplayName(), var3);
        }

    }

接下来看下doClassicBuildStages

 private void doClassicBuildStages(DefaultGradleLauncher.Stage upTo) {
    
    
        this.prepareSettings();
        if (upTo != DefaultGradleLauncher.Stage.LoadSettings) {
    
    
            this.prepareProjects();
            if (upTo != DefaultGradleLauncher.Stage.Configure) {
    
    
                this.prepareTaskExecution();
                if (upTo != DefaultGradleLauncher.Stage.TaskGraph) {
    
    
                    this.instantExecution.saveScheduledWork();
                    this.runWork();
                }
            }
        }
    }

这段代码,是按照状态划分,分别区分每个状态需要执行的方法

  • 当状态是LoadSettings时,执行prepareSettings,主要是加载setting.gralde文件,然后创建对应的project
  • 当状态是Configure,执行prepareProjects
  • 当状态是TaskGraph,执行prepareTaskExecution
  • 当状态是RunTasks,执行instantExecution.saveScheduledWork()和runWork()

下面继续看下prepareSettings方法

private void prepareSettings() {
    
    
        if (this.stage == null) {
    
    
            this.buildListener.buildStarted(this.gradle);
            this.settingsPreparer.prepareSettings(this.gradle);
            //把状态设置为LoadSettings
            this.stage = DefaultGradleLauncher.Stage.LoadSettings;
        }

    }

buildListener.buildStarted(this.gradle)

首先调用buildListener.buildStarted(this.gradle);通知构建开始,在之前的文章说过这个回调

settingsPreparer.prepareSettings(this.gradle);

然后执行到了DefaultSettingsPreparerprepareSettings方法

public void prepareSettings(GradleInternal gradle) {
    
    
        //执行init.gradle脚本
        this.initScriptHandler.executeScripts(gradle);
        SettingsLoader settingsLoader = gradle.getParent() != null ? this.settingsLoaderFactory.forNestedBuild() : this.settingsLoaderFactory.forTopLevelBuild();
        //查找并且加载setting.gradle的位置
        settingsLoader.findAndLoadSettings(gradle);
    }

prepareSettings主要做了俩件事

  • 执行init.gradle脚本
  • 查找并且加载setting.gradle的位置

而这里的findAndLoadSettings方法做了很多事情,如下:

  • 查找setting.gradle的位置
  • 编译buildSrc文件夹下的内容,这个就是之前说的buildSrc插件
  • 解析 gradle.properites
  • 解析setting.gradle
  • 创建project及subproject

二.configureBuild

执行完LoadSettings下面就是configureBuild配置阶段,而配置阶段所做的事情就是把gradle脚本编译成class,并执行,这个阶段执行prepareProjects方法

    private void prepareProjects() {
    
    
        if (this.stage == DefaultGradleLauncher.Stage.LoadSettings) {
    
    
            //准备classlocder
            ClassLoaderScope baseProjectClassLoaderScope = this.buildSourceBuilder.buildAndCreateClassLoader(this.gradle);
            this.gradle.setBaseProjectClassLoaderScope(baseProjectClassLoaderScope);
            //这里调用DefaultProjectsPreparer的prepareProjects方法
            this.projectsPreparer.prepareProjects(this.gradle);
            //把状态重置为Configure
            this.stage = DefaultGradleLauncher.Stage.Configure;
        }

    }

接下来看下DefaultProjectsPreparer的prepareProjects方法

public void prepareProjects(GradleInternal gradle) {
    
    
        this.maybeInformAboutIncubatingMode(gradle);
        this.buildLoader.load(gradle.getSettings(), gradle);
        if (gradle.getParent() == null) {
    
    
            this.buildRegistry.beforeConfigureRootBuild();
        }
        // 注释1
        if (gradle.getStartParameter().isConfigureOnDemand()) {
    
    
            this.projectConfigurer.configure(gradle.getRootProject());
        } else {
    
    
            //注释2
            this.projectConfigurer.configureHierarchy(gradle.getRootProject());
            (new ProjectsEvaluatedNotifier(this.buildOperationExecutor)).notify(gradle);
        }

        this.modelConfigurationListener.onConfigure(gradle);
    }
  • 注释1处:如果在 gradle.properties 文件中指定了参数 configure-on-demand,则只会配置主项目以及执行 task 所需要的项目。
  • 注释2处:如果没有配置指定参数那么,那么就去配置所有的项目,最后调用的是TaskPathProjectEvaluatorconfigureHierarchy方法
 public void configureHierarchy(ProjectInternal project) {
    
    
        this.configure(project);
        Iterator var2 = project.getSubprojects().iterator();

        while(var2.hasNext()) {
    
    
            Project sub = (Project)var2.next();
            this.configure((ProjectInternal)sub);
        }

    }

这里遍历所有的porject,然后配置了所有的project,configure方法最后会调用EvaluateProjectrun方法

     public void run(final BuildOperationContext context) {
    
    
            this.project.getMutationState().withMutableState(new Runnable() {
    
    
                public void run() {
    
    
                    try {
    
    
                        EvaluateProject.this.state.toBeforeEvaluate();
                        //回调ProjectEvaluationListener的beforeEvaluate接口
                        LifecycleProjectEvaluator.this.buildOperationExecutor.run(new LifecycleProjectEvaluator.NotifyBeforeEvaluate(EvaluateProject.this.project, EvaluateProject.this.state));
                        if (!EvaluateProject.this.state.hasFailure()) {
    
    
                            EvaluateProject.this.state.toEvaluate();

                            try {
    
    
                                 // 2、在 evaluate 方法中会设置默认的 init、wrapper task 和 默认插件,然后便会编译、执行 build.gradle 脚本
                                LifecycleProjectEvaluator.this.delegate.evaluate(EvaluateProject.this.project, EvaluateProject.this.state);
                            } catch (Exception var10) {
    
    
                                LifecycleProjectEvaluator.addConfigurationFailure(EvaluateProject.this.project, EvaluateProject.this.state, var10, context);
                            } finally {
    
    
                                EvaluateProject.this.state.toAfterEvaluate();
                                //回调ProjectEvaluationListener的afterEvaluate
                                LifecycleProjectEvaluator.this.buildOperationExecutor.run(new LifecycleProjectEvaluator.NotifyAfterEvaluate(EvaluateProject.this.project, EvaluateProject.this.state));
                            }
                        }

                        if (EvaluateProject.this.state.hasFailure()) {
    
    
                            EvaluateProject.this.state.rethrowFailure();
                        } else {
    
    
                            context.setResult(ConfigureProjectBuildOperationType.RESULT);
                        }
                    } finally {
    
    
                        EvaluateProject.this.state.configured();
                    }

                }
            });
        }

这个方法主要做了三件事情

  • 回调ProjectEvaluationListener 的 beforeEvaluate 接口
  • evaluate设置init 和 wrapper俩个默认task,设置默认的帮助插件org.gradle.help-tasks,并且编译并执行build.gradle
  • 回调 ProjectEvaluationListener.afterEvaluate 接口。

三. TaskGraph

执行完初始化和配置阶段,接下里就是配置task有向图了,这个阶段调用了DefaultGradleLauncher的prepareTaskExecution方法,创建一个有向无环图

 private void prepareTaskExecution() {
    
    
        if (this.stage == DefaultGradleLauncher.Stage.Configure) {
    
    
            this.taskExecutionPreparer.prepareForTaskExecution(this.gradle);
            //更改阶段为TaskGraph
            this.stage = DefaultGradleLauncher.Stage.TaskGraph;
        }
    }

接下来调用了BuildOperatingFiringTaskExecutionPreparer的prepareForTaskExecution

  public void prepareForTaskExecution(GradleInternal gradle) {
    
    
        this.buildOperationExecutor.run(new BuildOperatingFiringTaskExecutionPreparer.CalculateTaskGraph(gradle));
    }

然后调用了CalculateTaskGraph的run方法

  private class CalculateTaskGraph implements RunnableBuildOperation {
    
    

        public void run(BuildOperationContext buildOperationContext) {
    
    
            //填充任务图
            final TaskExecutionGraphInternal taskGraph = this.populateTaskGraph();
            buildOperationContext.setResult(new Result() {
    
    
                public List<String> getRequestedTaskPaths() {
    
    
                    return this.toTaskPaths(taskGraph.getRequestedTasks());
                }

                public List<String> getExcludedTaskPaths() {
    
    
                    return this.toTaskPaths(taskGraph.getFilteredTasks());
                }

                private List<String> toTaskPaths(Set<Task> tasks) {
    
    
                    return ImmutableSortedSet.copyOf(Collections2.transform(tasks, new Function<Task, String>() {
    
    
                        public String apply(Task task) {
    
    
                            return task.getPath();
                        }
                    })).asList();
                }
            });
        }
  }

这里直接调用populateTaskGraph方法填充任务图,我们看下这个方法

 TaskExecutionGraphInternal populateTaskGraph() {
    
    
            BuildOperatingFiringTaskExecutionPreparer.this.delegate.prepareForTaskExecution(this.gradle);
            return this.gradle.getTaskGraph();
        }

这里有调用了DefaultTaskExecutionPreparerprepareForTaskExecution方法

 public void prepareForTaskExecution(GradleInternal gradle) {
    
    
        //注释1 
        this.buildConfigurationActionExecuter.select(gradle);
        TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();
        //注释2 
        taskGraph.populate();
        this.includedBuildControllers.populateTaskGraphs();
        if (gradle.getStartParameter().isConfigureOnDemand()) {
    
    
            (new ProjectsEvaluatedNotifier(this.buildOperationExecutor)).notify(gradle);
        }

    }

先看下注释1处,最终调用了DefaultBuildConfigurationActionExecuterselect方法,源码如下

  public void select(final GradleInternal gradle) {
    
    
        this.projectStateRegistry.withLenientState(new Runnable() {
    
    
            public void run() {
    
    
                //创建集合
                List<BuildConfigurationAction> processingBuildActions = CollectionUtils.flattenCollections(BuildConfigurationAction.class, new Object[]{
    
    DefaultBuildConfigurationActionExecuter.this.configurationActions, DefaultBuildConfigurationActionExecuter.this.taskSelectors});
                //然后调用了configure方法
                DefaultBuildConfigurationActionExecuter.this.configure(processingBuildActions, gradle, 0);
            }
        });
    }

需要注意的是,首先创建了一个List,然后调用了configure方法,我们看下configure方法的源码

  private void configure(final List<BuildConfigurationAction> processingConfigurationActions, final GradleInternal gradle, final int index) {
    
    
        if (index < processingConfigurationActions.size()) {
    
    
            ((BuildConfigurationAction)processingConfigurationActions.get(index)).configure(new BuildExecutionContext() {
    
    
                public GradleInternal getGradle() {
    
    
                    return gradle;
                }

                public void proceed() {
    
    
                    DefaultBuildConfigurationActionExecuter.this.configure(processingConfigurationActions, gradle, index + 1);
                }
            });
        }
    }

这里可以看到其实就是依次从List中取出类,然后依次执行ExcludedTaskFilteringBuildConfigurationAction,DefaultTasksBuildExecutionAction
TaskNameResolvingBuildConfigurationAction,执行类的configure方法

下面依次看下这几个类的configure方法

ExcludedTaskFilteringBuildConfigurationAction ## configure

  public void configure(BuildExecutionContext context) {
    
    
        GradleInternal gradle = context.getGradle();
        //获取需要排除的task
        Set<String> excludedTaskNames = gradle.getStartParameter().getExcludedTaskNames();
        if (!excludedTaskNames.isEmpty()) {
    
    
            Set<Spec<Task>> filters = new HashSet();
            Iterator var5 = excludedTaskNames.iterator();

            while(var5.hasNext()) {
    
    
                String taskName = (String)var5.next();
                filters.add(this.taskSelector.getFilter(taskName));
            }
            //给TaskGraph,添加需要过滤的task
            gradle.getTaskGraph().useFilter(Specs.intersect(filters));
        }

        context.proceed();
    }

这里主要是给TaskGraph设置了filter去处理需要排除的task,以便后面计算依赖的时候排除相应的task

DefaultTasksBuildExecutionAction ## configure

   public void configure(BuildExecutionContext context) {
    
    
        StartParameter startParameter = context.getGradle().getStartParameter();
        Iterator var3 = startParameter.getTaskRequests().iterator();

        TaskExecutionRequest request;
        do {
    
    
            if (!var3.hasNext()) {
    
    
                ProjectInternal project = context.getGradle().getDefaultProject();
                this.projectConfigurer.configure(project);
                List<String> defaultTasks = project.getDefaultTasks();
                if (defaultTasks.size() == 0) {
    
    
                    defaultTasks = Collections.singletonList("help");
                    LOGGER.info("No tasks specified. Using default task {}", GUtil.toString(defaultTasks));
                } else {
    
    
                    LOGGER.info("No tasks specified. Using project default tasks {}", GUtil.toString(defaultTasks));
                }

                startParameter.setTaskNames(defaultTasks);
                context.proceed();
                return;
            }

            request = (TaskExecutionRequest)var3.next();
        } while(request.getArgs().isEmpty());

        context.proceed();
    }

这里会检查命令行会不会传进来Task的名称,如果指定了要执行的Task,那么什么都不做

如果没有指定就看project中是否有默认的Task,默认的task可以通过defaultTasks在build.gradle中指定

如果默认的task也没有,那就把指定Task 设置为 Help Task

TaskNameResolvingBuildConfigurationAction ## configure

 public void configure(BuildExecutionContext context) {
    
    
        GradleInternal gradle = context.getGradle();
        TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();
        List<TaskExecutionRequest> taskParameters = gradle.getStartParameter().getTaskRequests();
        Iterator var5 = taskParameters.iterator();

        while(var5.hasNext()) {
    
    
            TaskExecutionRequest taskParameter = (TaskExecutionRequest)var5.next();
            //解析task
            List<TaskSelection> taskSelections = this.commandLineTaskParser.parseTasks(taskParameter);
            Iterator var8 = taskSelections.iterator();

            //把task添加到taskGraph中
            while(var8.hasNext()) {
    
    
                TaskSelection taskSelection = (TaskSelection)var8.next();
                LOGGER.info("Selected primary task '{}' from project {}", taskSelection.getTaskName(), taskSelection.getProjectPath());
                taskGraph.addEntryTasks(taskSelection.getTasks());
            }
        }

        context.proceed();
    }

这里主要有俩个操作

  • 解析Tasks:分析命令行中task 是否指定了Project,如果指定了就拿到改Project中的task,如果没有指定,则会把所有project中的符合task name的全部筛选出来
  • 遍历并添加所有已选择的 Tasks 至 taskGraph 实例之中,这里会处理 task 的依赖关系,包括 dependson finalizedby mustrunafter shouldrunafter,然后把信息都保存在 org.gradle.execution.taskgraph.TaskInfo 里

最后回到DefaultTaskExecutionPreparer 的 prepareForTaskExecution 注释2 处

调用taskGraph 的 populate方法,根据上一步的计算的task和依赖关系,生成task图

四.RunTasks

接下来看下RunTasks阶段

 private void doClassicBuildStages(DefaultGradleLauncher.Stage upTo) {
    
    
        this.prepareSettings();
        if (upTo != DefaultGradleLauncher.Stage.LoadSettings) {
    
    
            this.prepareProjects();
            if (upTo != DefaultGradleLauncher.Stage.Configure) {
    
    
                this.prepareTaskExecution();
                if (upTo != DefaultGradleLauncher.Stage.TaskGraph) {
    
    
                    this.instantExecution.saveTaskGraph();
                    // 注释1
                    this.runWork();
                }
            }
        }
}

RunTasks阶段调用了注释1 处的runWork()方法,我们看下详细代码

 private void runWork() {
    
    
        if (this.stage != DefaultGradleLauncher.Stage.TaskGraph) {
    
    
            throw new IllegalStateException("Cannot execute tasks: current stage = " + this.stage);
        } else {
    
    
            List<Throwable> taskFailures = new ArrayList();
            //注释1
            this.buildExecuter.execute(this.gradle, taskFailures);
            if (!taskFailures.isEmpty()) {
    
    
                throw new MultipleBuildFailures(taskFailures);
            } else {
    
    
                this.stage = DefaultGradleLauncher.Stage.RunTasks;
            }
        }
    }

注释1处调用了DefaultBuildWorkExecutor的execute方法


 public void execute(GradleInternal gradle, Collection<? super Throwable> failures) {
    
    
        this.execute(gradle, 0, failures);
    }


 private void execute(final GradleInternal gradle, final int index, final Collection<? super Throwable> taskFailures) {
    
    
        if (index < this.executionActions.size()) {
    
    
            //执行list中类的execute方法
            ((BuildExecutionAction)this.executionActions.get(index)).execute(new BuildExecutionContext() {
    
    
                public GradleInternal getGradle() {
    
    
                    return gradle;
                }

                public void proceed() {
    
    
                    //上一个工执行完成之后,拿到list中下一个执行
                    DefaultBuildWorkExecutor.this.execute(gradle, index + 1, taskFailures);
                }
            }, taskFailures);
        }
    }

这个会首先调用DryRunBuildExecutionActionexecute方法

    public void execute(BuildExecutionContext context, Collection<? super Throwable> taskFailures) {
    
    
        GradleInternal gradle = context.getGradle();
        //注释1 
        if (gradle.getStartParameter().isDryRun()) {
    
    
            Iterator var4 = gradle.getTaskGraph().getAllTasks().iterator();

            while(var4.hasNext()) {
    
    
                Task task = (Task)var4.next();
                this.textOutputFactory.create(DryRunBuildExecutionAction.class).append(((TaskInternal)task).getIdentityPath().getPath()).append(" ").style(Style.ProgressStatus).append("SKIPPED").println();
            }
        } else {
    
    
            context.proceed();
        }

    }
}

在注释1处查看命令行中是否有参数--dry-run,如果有的话就跳过这个task的执行,并输出task名称并且打印出先后关系

然后执行SelectedTaskExecutionAction的execute方法

 public void execute(BuildExecutionContext context, Collection<? super Throwable> taskFailures) {
    
    
        GradleInternal gradle = context.getGradle();
        TaskExecutionGraphInternal taskGraph = gradle.getTaskGraph();
        if (gradle.getStartParameter().isContinueOnFailure()) {
    
    
            taskGraph.setContinueOnFailure(true);
        }

        taskGraph.addTaskExecutionGraphListener(new SelectedTaskExecutionAction.BindAllReferencesOfProjectsToExecuteListener());
        //注释1
        taskGraph.execute(taskFailures);
    }

在注释1处调用了DefaultTaskExecutionGraphexecute方法,我们看下具体代码

 public void execute(Collection<? super Throwable> failures) {
    
    
        ProjectExecutionServiceRegistry projectExecutionServices = new ProjectExecutionServiceRegistry(this.globalServices);

        try {
    
    
            //注释1 
            this.executeWithServices(projectExecutionServices, failures);
        } finally {
    
    
            projectExecutionServices.close();
        }

    }

在注释1 处调用了executeWithServices方法,看下源码

   private void executeWithServices(ProjectExecutionServiceRegistry projectExecutionServices, Collection<? super Throwable> failures) {
    
    
        ...

        try {
    
    
            //注释1
            this.planExecutor.process(this.executionPlan, failures, new DefaultTaskExecutionGraph.BuildOperationAwareExecutionAction(this.buildOperationExecutor.getCurrentOperation(), new DefaultTaskExecutionGraph.InvokeNodeExecutorsAction(this.nodeExecutors, projectExecutionServices)));
            LOGGER.debug("Timing: Executing the DAG took " + clock.getElapsed());
        } finally {
    
    
       ...
        }

    }

在注释1处调用了planExecutor.process,最终是调用了DefaultPlanExecutor的process方法

 public void process(ExecutionPlan executionPlan, Collection<? super Throwable> failures, Action<Node> nodeExecutor) {
    
    
        ManagedExecutor executor = this.executorFactory.create("Execution worker for '" + executionPlan.getDisplayName() + "'");

        try {
    
    
            WorkerLease parentWorkerLease = this.workerLeaseService.getCurrentWorkerLease();
            //注释1
            this.startAdditionalWorkers(executionPlan, nodeExecutor, executor, parentWorkerLease);
            (new DefaultPlanExecutor.ExecutorWorker(executionPlan, nodeExecutor, parentWorkerLease, this.cancellationToken, this.coordinationService)).run();
            this.awaitCompletion(executionPlan, failures);
        } finally {
    
    
            executor.stop();
        }

    }

在注释1 处调用了startAdditionalWorkers方法

 private void startAdditionalWorkers(ExecutionPlan executionPlan, Action<? super Node> nodeExecutor, Executor executor, WorkerLease parentWorkerLease) {
    
    
        LOGGER.debug("Using {} parallel executor threads", this.executorCount);

        for(int i = 1; i < this.executorCount; ++i) {
    
    
            executor.execute(new DefaultPlanExecutor.ExecutorWorker(executionPlan, nodeExecutor, parentWorkerLease, this.cancellationToken, this.coordinationService));
        }

    }

在这里出创建了线程去处理task,默认是8个线程执行task

执行Task前的一些预处理

首先,回调 TaskExecutionListener#beforeExecute。

CatchExceptionTaskExecuter.execute // 加了 try catch,防止执行过程中异常   
ExecuteAtMostOnceTaskExecuter.execute  // 判断 task 是否执行过   
SkipOnlyIfTaskExecuter.execute  // 判断 task 的 onlyif 条件是否满足执行   
SkipTaskWithNoActionsExecuter.execute  // 跳过没有 action 的 task,没有  action 说明 task 不需要执行   
ResolveTaskArtifactStateTaskExecuter.execute  // 设置 artifact 状态    
SkipEmptySourceFilesTaskExecuter.execute  // 跳过设置了 source file 但是 source file 为空的 task,source file 为空说明 task 没有需要处理的资源   
ValidatingTaskExecuter.execute()  // 确认 task 是否可以执行   
ResolveTaskOutputCachingStateExecuter.execute // 处理 task output 缓存   
SkipUpToDateTaskExecuter.execute  // 跳过 update-to-date 的 task    
ExecuteActionsTaskExecuter.execute // 真正执行 task   

真正执行task

最终调用ExecuteActionsTaskExecuter.TaskExecutionexecute来真正执行task

   public WorkResult execute(@Nullable InputChangesInternal inputChanges, InputChangesContext context) {
    
    
            ....

            WorkResult var5;
            try {
    
    
                var5 = this.executeWithPreviousOutputFiles(inputChanges);
            } finally {
    
    
                outputs.setPreviousOutputFiles((FileCollection)null);
            }

            return var5;
        }

    private WorkResult executeWithPreviousOutputFiles(@Nullable InputChangesInternal inputChanges) {
    
    
            this.task.getState().setExecuting(true);

            WorkResult var2;
            try {
    
    
                ExecuteActionsTaskExecuter.LOGGER.debug("Executing actions for {}.", this.task);
                //回调 TaskActionListener 的 beforeActions 接口。
                ExecuteActionsTaskExecuter.this.actionListener.beforeActions(this.task);
                //遍历执行执行所有Action
                ExecuteActionsTaskExecuter.this.executeActions(this.task, inputChanges);
                var2 = this.task.getState().getDidWork() ? WorkResult.DID_WORK : WorkResult.DID_NO_WORK;
            } finally {
    
    
                this.task.getState().setExecuting(false);
                //回调 TaskActionListener 的 beforeActions 接口。
                ExecuteActionsTaskExecuter.this.actionListener.afterActions(this.task);
            }

            return var2;
        }

这里主要做了三件事

  • 回调 TaskActionListener 的 beforeActions 接口。
  • 遍历执行执行所有Action,执行Task的本质就是执行Action
  • 回调 TaskActionListener 的 beforeActions 接口。

五.Finish

在 Finished 阶段仅仅只干了一件比较重要的事情,就是 回调 buildListener 的 buildFinished 接口

这里借用【Android 修炼手册】Gradle 篇 – Gradle 源码分析
中的一个流程图,来展示真个流程的顺序

image.png

总结

这个gradle构建可以简单总结为一下几个步骤

  • 解析seeting.gradle并执行,生成project实例
  • 解析build.gradle并执行
  • 生成task依赖图
  • 执行task

参考

主要参考以下博客,感谢大佬们的付出

【Android 修炼手册】Gradle 篇 – Gradle 源码分析

【【灵魂七问】深度探索 Gradle 自动化构建技术(五、Gradle 插件架构实现原理剖析 — 上)

猜你喜欢

转载自blog.csdn.net/qq_34760508/article/details/117781768