详解Gradle构建过程

Gradle构建过程

根据在上图中所示,Gradle 的构建过程主要分为三个阶段:

  • 初始化阶段
  • 配置阶段
  • 执行阶段

监听Gradle初始化时机

在这个初始化阶段中主要有两个时机需要关注:

setting.gradle 执行结束的监听

//1.setting.gradle 执行结束的监听
gradle.settingsEvaluated {
    println "settings.gradle 初始化执行结束"
}

参与构建的Project对象创建完毕的监听

//2.参与构建的Project对象创建完毕的监听
gradle.projectsLoaded {
    Gradle gradle ->
        println "settings.gradle 所有在 settings 中 include 的 Project 都创建完成了"
}

监听Gradle配置阶段时机

在 settings.gradle 中可以配置需要参与构建的 project ,并且在初始化阶段就已经创建好对应的 project 实例了。
Gradle 的配置阶段就是执行每一个 Project 对应的 build.gradle 的配置代码。

下面相关的API是关于配置的回调:

gradle.beforeProject

表示对每一个 project 在执行配置代码之前都会回调这个方法。

gradle.beforeProject {
    Project project ->
        println ">>>>>>>>gradle beforeProject " + project.name + " 配置开始前回调"
}

project.beforeEvaluate

当前 project在执行配置代码之前的回调

通过 gradle.afterProject 和 project.afterEvaluate 是差不多一下的。

this.afterEvaluate {
    project ->
        println project.name + " 配置结束监听"
}

gradle.projectsEvaluated

表示所有的 project 都执行完对应的 build.gradle 的配置代码,准备要去生成对应的 Task 依赖图。

gradle.projectsEvaluated {
    gradle ->
        println "所有的project都配置完毕了,准备生成Task依赖关系"
}

gradle.taskGraph.whenReady

表示 "task 依赖关系已经生成"

gradle.taskGraph.whenReady {
    TaskExecutionGraph graph ->
        println "task 依赖关系已经生成"
}

监听Gradle执行阶段时机

Gradle 在配置阶段中会执行每一个 project 的 build.gradle 的配置代码,并且最终生成每一个 Task 任务的依赖关系。下面到了执行阶段就会根据这个依赖关系去执行对应的 Task 任务。

gradle.taskGraph.beforeTask

每一个 Task 任务执行之前回调

gradle.taskGraph.beforeTask {
    Task task ->
        println "Project[${task.project.name}]--->Task[${task.name}] 在执行之前被回调"
}

gradle.taskGraph.afterTask

每一个 task 执行之后被回调

gradle.taskGraph.afterTask {
    task, TaskState taskState ->
        //第二个参数表示 task 的状态,是可选的参数
        println "Project[${task.project.name}]--->Task[${task.name}] 在执行完毕,taskState[upToDate:${taskState.upToDate},skipped:${taskState.skipped},executed:${taskState.executed},didWork:${taskState.didWork}]"
}

Gradle 构建执行结束的回调

gradle.buildFinished

当所有的任务执行完毕的回调

gradle.buildFinished {
    BuildResult buildResult ->
        println "构建完毕"
}

计算 build 任务的执行时长

在 Android 中 build 的执行是最为复杂,也是执行时间最久的一个 Task ,因为 build 这个任务依赖了很多其他的任务,第一个被依赖的任务是 preBuild ,因此我们希望在 preBuild 执行之前记录当前的时间戳taskStartTime,在 build 执行完毕之后记录当前的时间戳taskEndTime,然后计算两个时间戳的差值即是 build 任务的执行时长啦。

下面是具体的步骤:

  • 通过 project(":app") 对 app module 单独配置。
  • 通过 project.afterEvaluate 监听 project 配置完毕。
  • 通过 getBuildTask 获取 preBuild 和 build 两个任务对象。
  • 监听 preBuild.doFirst 得到开始执行的时间戳。
  • 监听 build.doLast 得到执行完毕的时间戳。
  • 最后得到两个时间戳的差值即是该任务的执行市场。
  • 执行 build 任务。
//配置 app module
project(":app") {
    Project project ->
        project.afterEvaluate {
            //获取build task 任务
            Task buildTask = getBuildTask(project, ":app:build")
            //获取 preBuild 任务
            Task preBuildTask = getBuildTask(project, ":app:preBuild")

            def taskStartTime = 0
            def taskEndTime = 0

            //在preBuild task 中追加一个监听获取在preBuild执行之前的时间戳的 action
            preBuildTask.doFirst {
                taskStartTime = System.currentTimeMillis()
            }
            //在build task 中追加一个监听获取执行完毕的时间戳的 action
            buildTask.doLast {
                taskEndTime = System.currentTimeMillis()
                println "build task 执行时间:${taskEndTime - taskStartTime}"
            }
        }
}

/**
 * 获取该project对应的build任务
 * @param project
 * @return
 */
Task getBuildTask(Project project, String taskPath) {

    //获取该project管理task的容器
    TaskContainer taskContainer = project.getTasks()

    //拿到build的Task对象
    Task buildTask = taskContainer.getByPath(taskPath)

    return buildTask
}

执行build任务

./gradlew build

以上就是详解Gradle构建过程的详细内容,更多关于Gradle构建过程的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android App开发中Gradle构建过程的配置方法

    在build文件中使用了Android或者Java插件之后就会自动创建一系列可以运行的任务. Gradle中有如下一下默认约定的任务: 1. assemble 该任务包含了项目中的所有打包相关的任务,比如java项目中打的jar包,Android项目中打的apk 2. check 该任务包含了项目中所有验证相关的任务,比如运行测试的任务 3. build 该任务包含了assemble和check 4. clean 该任务会清空项目的所有的输出,删除所有在assemble任务中打的包 assemb

  • android studio更新gradle错误构建项目失败的解决方法

    一.版本错误 对应版本,修改gradle version,和plusing version两个地方修改gradle version,和plusing version的方法有两种,一种是在 project.build.这里plusing version的设置 buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.3.0' } } allprojects

  • gradle中的增量构建浅析

    文章目录 简介增量构建自定义inputs和outputs运行时API隐式依赖输入校验自定义缓存方法输入归一化其他使用技巧 简介 在我们使用的各种工具中,为了提升工作效率,总会使用到各种各样的缓存技术,比如说docker中的layer就是缓存了之前构建的image.在gradle中这种以task组合起来的构建工具也不例外,在gradle中,这种技术叫做增量构建. 增量构建 gradle为了提升构建的效率,提出了增量构建的概念,为了实现增量构建,gradle将每一个task都分成了三部分,分别是in

  • Android Studio 中的Gradle构建系统示例

    相信有很多像我一样的朋友在使用Android Studio时,对 Gradle 和 Gradle Android 插件的版本号和作用不是很清楚,本篇文章的将对这些进行解释,最后通过一个实际的项目工程来说明其中的配置块的含义,并通过源代码的角度去剖析脚本的结构. 一.第一部分:Q&A 1.Gradle是什么? Gradle 是一个JVM平台上的自动化的构建工具,支持多项目构建,强有力依赖管理(本地或者远程依赖),构建脚本使用Groovy语言编写. 在Android Studio的 project

  • Gradle构建多模块项目的方法步骤

    通常我在使用Maven构建项目的时候是将应用项目划分为多个更小的模块. Gradle 项目也拥有多于一个组件,我们也将其称之为多项目构建(multi-project build). 我们首先创建一个多项目构建: mkdir cmdGradleProj && cd cmdGradleProj gradle init 这时候 D:\cmdGradleProj> 目录下执行:tree /f 的项目结构如下: │ build.gradle │ gradlew │ gradlew.bat │

  • 详解Gradle构建过程

    Gradle构建过程 根据在上图中所示,Gradle 的构建过程主要分为三个阶段: 初始化阶段 配置阶段 执行阶段 监听Gradle初始化时机 在这个初始化阶段中主要有两个时机需要关注: setting.gradle 执行结束的监听 //1.setting.gradle 执行结束的监听 gradle.settingsEvaluated { println "settings.gradle 初始化执行结束" } 参与构建的Project对象创建完毕的监听 //2.参与构建的Project

  • 详解Android系统启动过程

    计算机是如何启动的 计算机的硬件包括:CPU,内存,硬盘,显卡,显示器,键盘鼠标等输入输出设备.所有的软件都是存放在硬盘中,程序执行时,需要将程序从硬盘上读取到内存中,然后加载到CPU中来运行.当按下开机键时,内存中什么都没有,因此需要借助某种方式,将操作系统加载到内存中,而完成这项任务的就是BIOS. 引导阶段 BIOS:BIOS是主板芯片上的一个程序,计算机通电后,第一件事情就是读取BIOS. BIOS首先进行硬件检测,检查计算机硬件能否满足运行的基本条件.如果硬件出现问题,主板发出不同的蜂

  • 详解nginx安装过程并代理下载服务器文件

    主旨 nginx服务,现在是最好用的一种代理服务,日常我们代理的一般都是端口转发和流量控制,那么我们如何通过nginx来实现文件下载呢?就是通过nginx服务,通过url来下载文件. Nginx是一款轻量级的web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行.其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好. 环境 linux服务器nginx软件 软件下载 链接: https://pan.baidu.co

  • C语言 图文并茂详解程序编译过程

    目录 一.初识编译器 二.程序被编译的过程 三.小结 一.初识编译器 编译器是一个广义的概念,真正的编译器由下面几个模块组成,真正的编译器是进行语法分析和语义分析的. 二.程序被编译的过程 如下,file.i 是中间代码,file.s 是一个汇编文件,file.o 是二进制文件. 预编译 处理所有的注释,以空格代替 将所有的 #define 删除,并且展开所有的宏定义 处理条件编译指令 #if, #ifdef, #elif,#else,#endif 处理 #include,展开被包含的文件 保留

  • SpringBoot详解整合MyBatis过程中可能遇到的问题

    尽量不要用 jUnit 提供的单元测试 提一个要求尽量使用SpringBoot 提供的测试类进行测试,能够自动扫描组件以及使用容器中的bean对象 还有如果有组件 中存在注入对象的话,那么必须在SpringBoot容器中取出 这个组件,进而使用注入的对象的功能!!! 今天有个错误,花了很长时间来解决,最后发现是一个很低级很基础的错误! 这是mapper接口,使用@mapper 相当于将接口的代理对象注册进入bean中,但是上下文中找不到(其实是正常) 因为 @Mapper 这个注解是 Mybat

  • MySQL索引详解及演进过程及面试题延伸

    目录 1索引的概念 1.1定义 1.2类型 1.3作用 2索引的数据结构B+树的演进过程 2.1问题 2.2问题 2.3问题:怎么建目录呢?给每一个页都建一个目录吗? 2.4索引树.页的分裂与合并 2.5根据我们刚才推演的,延申出几个面试题 3什么是二级索引树 3.1那么二级索引树怎么排序? 3.2索引桥的概念是什么呢(最左匹配原则)? 3.3回表.覆盖索引.索引下推 3.4延申几个面试题: 3.5二级索引树的总结 4主键索引与二级索引的区别 1索引的概念 1.1定义 索引在关系型数据库中,是一

  • Springboot详解底层启动过程

    目录 SpringApplication构造分析 SpringApplication run分析 SpringApplication构造分析 1.记录 BeanDefinition 源 spring容器刚开始是空的,要去各个源找到beanDefinition,这些源可能是配置类,可能是xml文件.在构造方法里会获取一个主源,也就是引导类,根据引导类去获取beanDefinition. 2.推断应用类型 根据jar包去判断是什么引用类型 3.记录 ApplicationContext 初始化器 对

  • 详解java构建者模式Builder

    定义 Builder模式是一步步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构建过程.该模式是将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离. 作为复杂对象可能有很多组成部分,比如汽车有车轮.方向盘.发动机.变速箱还有各种小零件等,如何将这些部件组装成一台汽车,这个装配的过程漫长且复杂,对于这种情况,为了对外部隐藏实现细节,就可以使用Builder模式将部件和组装过程分离,使得构建过程和部件分离可自由扩展,两者之间的耦合也降到最低

  • 详解如何构建自己的react hooks

    1. 常用的一个 hooks 官方中提供了几个内置的钩子,我们简单了解下他们的用法. 1.1 useState: 状态钩子 需要更新页面状态的数据,我们可以把他放到 useState 的钩子里.例如点击按钮一下,数据加 1 的操作: const [count, setCount] = useState(0); return (<> <p>{ count}</p> <button onClick = { () => setCount(count + 1) }&

随机推荐