• Gradle-构建过程&计算build执行时长


    Gradle-构建过程&计算build执行时长

    来源 https://www.jianshu.com/p/e7a40a592f15

    # 任务

    • 图解 Gradle 构建的三个阶段
    • 监听 Gradle 不同阶段的回调;
    • 练习-计算 build 任务的执行时长;

    # 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

    ============= End
     
  • 相关阅读:
    Android NDK 学习之传递类对象
    https://www.aminer.cn/ AI研究
    MYSQL 的一些文件及说明
    Windows下移动MariaDB数据目录 (转!)
    MariaDB Galera Cluster 10.1 只支持 LINUX ?!
    MARIADB 在 OPENSUSE 的安装。
    “命令行程序”的通用图形界面 (转)
    代码生成的地址:mygeneration
    上海力软--快速开发框架
    康力优蓝机器人 -- 优友U05类人型机器人发布
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/13383021.html
Copyright © 2020-2023  润新知