• Gradle系列【6】生命周期


    有道无术,术尚可求,有术无道,止于术。

    构建生命周期

    Gradle 的核心是一种基于依赖的编程语言。在Gradle 术语中,这意味着您可以定义任务和任务之间的依赖关系。Gradle 保证这些任务按照它们的依赖顺序执行,并且每个任务只执行一次。

    这些任务形成了一个有向无环图。有一些构建工具可以在执行任务时构建这样的依赖关系图。Gradle 在执行任何任务之前构建完整的依赖关系图。这是 Gradle 的核心,它使许多原本不可能的事情成为可能。

    构建阶段

    Gradle 构建具有三个不同的阶段。

    • 初始化:Gradle 支持单项目和多项目构建。在初始化阶段,Gradle 确定哪些项目将参与构建,并为每个项目创建一个Project实例。

    • 配置:解析所有project中的build.gradle文件获取所有的task,形成有向无环图后执行依赖关系。并且所有project中的build script部分和task的配置段会在这一阶段调用(注意并不是执行具体的task代码)。

    • 执行任务:Gradle 确定在配置阶段创建和配置的要执行的任务子集。该子集由传递给gradle命令和当前目录的任务名称参数确定。Gradle 然后执行每个选定的任务。

    settings 文件

    除了构建脚本文件,Gradle 还定义了一个settings 文件,该文件由 Gradle 通过命名约定确定,默认名称是settings.gradle

    settings 文件在初始化阶段执行,多项目构建必须在settings.gradle定义项目层次结构。这是必需的,因为文件定义了哪些项目参与了多项目构建。对于单项目构建,设置文件是可选的。

    声明实例化和配置Project参与构建的实例层次结构所需的配置。

    Settings实例和settings.gradle文件之间存在一一对应的关系。在 Gradle 构建项目之前,会创建一个 Settings实例

    Settings实例的属性如下图:
    在这里插入图片描述
    Settings实例的方法如下图:
    在这里插入图片描述
    在这里插入图片描述

    生命周期监听

    gradle在生命周期三个阶段都设置了相应的钩子函数调用。

    初始化

    在这里插入图片描述

    //settings.gradle
    gradle.beforeSettings {
        //Gradle.buildStarted()在6.0中弃用,7.0中彻底删除,采用beforeSettings替代
        println '在settings加载之前执行,但是这个函数又放在了settings中,所以不会执行'
    }
    gradle.settingsEvaluated {
        println 'settings脚本执行完成之后调用'
    }
    //每个module的build.gradle执行之前都会调用,闭包会传入当前的project对象作为参数
    gradle.projectsLoaded {
        println "所有的project对象加载完成"
    }
    
    //上述的写法也可以采用如下方式书写
    gradle.addBuildListener(new BuildListener() {
        @Override
        void beforeSettings(Settings settings) {
            super.beforeSettings(settings)
        }  
        @Override
        void settingsEvaluated(Settings settings) {}
        @Override
        void projectsLoaded(Gradle gradle) {}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    配置

    在这里插入图片描述

    //settings.gradle
    //每个module的build.gradle执行之前都会调用,闭包会传入当前的project对象作为参数
    //注意:如果在build.gradle中书写project.beforeProject闭包并不会执行(子模块的情况另说),参照gradle.beforeSettings函数
    gradle.beforeProject{ project ->
        println 'beforeProject $project'
    }
    gradle.afterProject{ project ->
        println 'afterProject $project'
    }
    
    //所有module的build.gradle脚本执行完成之后,表示build.gradle执行完成
    gradle.projectsEvaluated {
        println 'projectsEvaluated'
    }
    
    // task有向无环图构建完成,配置阶段完成,TaskExecutionGraph对象作为对象传入闭包
    gradle.taskGraph.whenReady { graph ->
        println 'whenReady'
    }
    // 同gradle.taskGraph.whenReady
    gradle.addListener(new TaskExecutionGraphListener() {
        @Override
        void graphPopulated(TaskExecutionGraph taskExecutionGraph) {
            println "TaskExecutionGraphListener.graphPopulated"
        }
    })
    
    • 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
    //project.beforeEvaluate的执行时机
    public class DemoPlugin implements Plugin<Project> {
        @Override
        public void apply(Project project) {
            project.beforeEvaluate {
                println("beforeEvaluate")
            }
        }
    }
    //如果这个DemoPlugin是被写在`build.gradle`文件里,像这样`apply plugin: 'demoPlugin'`,`beforeEvaluate()`方法不会执行,而如果是在rootPlugin里,调用subProject的`apply plugin 'demoPlugin'`,则`beforeEvaluate()`会被执行。原因是`beforeEvaluate()`这个方法是在解析`build.gradle`文件之前执行,在`build.gradle`中才注册`beforeEvaluate()`监听方法,已经晚了。
    
    基于此,我们想在解析`build.gradle`之前,改变`build.gradle`文件的内容,可以在
    beforeEvaluate() 这个方法里修改`build.gradle`。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    执行

    在这里插入图片描述

    //settings.gradle
    gradle.taskGraph.beforeTask {
    	//7.3已过时,8.0中将删除
    }
    
    gradle.taskGraph.afterTask {
    	//7.3已过时,8.0中将删除
    }
    
    //或者如下写法
    gradle.addListener(new TaskActionListener() {
        @Override
        void beforeActions(Task task) {
        }
        @Override
        void afterActions(Task task) {
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    文档参考来源

    君哥的学习笔记

  • 相关阅读:
    小程序:如何合理规划分包使主包不超过2M
    所谓0脂低卡的代糖如何影响血糖和胰岛素你真的了解吗?
    【经验分享】基于Linux命令行编程环境的栈追溯和反汇编技术实践分享
    C++ map容器的简单用法
    给定一个整数N,代表你有1~N这些数字。在给定一个整数K。你可以随意排列这些数字,但是每一种排列都有若干个逆序对。返回有多少种排列,正好有K个逆序对。
    HIve数仓新零售项目DWB层的构建
    十、【分布式微服务企业快速架构】SpringCloud分布式、微服务、云架构之Eclipse 创建 Java 包
    binary.write 和 binary.read
    力扣21 - 合并两个有序链表【归并排序思维】
    在YesDev研发协同工具,项目协作 All In One
  • 原文地址:https://blog.csdn.net/qq_43437874/article/details/125381824