| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> 从Gradle生命周期到自定义Task挂接到Build构建流程全解 -> 正文阅读 |
|
[移动开发]从Gradle生命周期到自定义Task挂接到Build构建流程全解 |
} void settingsEvaluated(Settings var1) { println ‘settingsEvaluated()->settings评估完成(settins.gradle中代码执行完毕)’ // var1.gradle.rootProject 这里访问Project对象时会报错,还未完成Project的初始化 } void projectsLoaded(Gradle var1) { println ‘projectsLoaded()->项目结构加载完成(初始化阶段结束)’ println ‘projectsLoaded()->初始化结束,可访问根项目:’ + var1.gradle.rootProject } void projectsEvaluated(Gradle var1) { println ‘projectsEvaluated()->所有项目评估完成(配置阶段结束)’ } void buildFinished(BuildResult var1) { println 'buildFinished()->构建结束 ’ } }) 在 build.gradle 文件中,也可以拿到 Gradle 对象,但如果在 build.gradle 文件中添加上面的监听事件的话,buildStarted,settingsEvaluated 和 projectsLoaded 方法是不会回调的,因为这三个方法是在初始化阶段 执行 settings.gradle 文件的时候执行的,但另外两个方法是会回调的。 在根工程的 build.gradle 文件中,增加如下代码,以便更好的观察上面添加的监听事件的回调时机: allprojects { afterEvaluate { println “${name}:配置完成” } } 打印信息如下:
配置阶段的任务:是执行各项目下的 2-1、配置阶段执行的代码配置阶段也是我们最常接触到的构建阶段,比如应用外部构建插件 每个
验证:在根目录的 println ‘build.gradle的配置阶段’ // 调用Project的dependencies(Closure c)声明项目依赖 dependencies { // 闭包中执行的代码 println ‘dependencies中执行的代码’ } // 创建一个Task task test() { println ‘Task中的配置代码’ // 定义一个闭包 def a = { println ‘Task中的配置代码2’ } // 执行闭包 a() doFirst { println ‘这段代码配置阶段不执行’ } } println ‘我是顺序执行的’ 打印信息如下:
从上面的打印信息可以看出,在执行了dependencies的闭包后,直接执行的是任务test中的配置段代码( 需要注意的是,执行任何 Gradle 命令,在初始化阶段和配置阶段的代码都会被执行。 2-2、Task 依赖关系配置完成监听配置阶段另外一个重要的任务就是 构建 Task 依赖关系的有向无环图,说简单一点,就是给 所有的 Task 排一个执行顺序,在执行阶段的时候,就按照这个顺序去执行所有的 Task 任务。 我们可以通过 Gradle 对象的 getTaskGraph 方法来得到该有向无环图对象: TaskExecutionGraph,通过TaskExecutionGraph类的相关方法可以监听 Task 依赖关系构建完成的通知,如: void whenReady(Closure var1) void addTaskExecutionGraphListener(TaskExecutionGraphListener var1) 在 build.gradle 文件中,增加如下代码: gradle.getTaskGraph().whenReady { println “whenReady Task依赖关系构建完成,size=${it.allTasks.size()}” it.allTasks.forEach { task -> println “${task.name}” } } gradle.getTaskGraph().addTaskExecutionGraphListener(new TaskExecutionGraphListener() { @Override void graphPopulated(TaskExecutionGraph graph) { println “graphPopulated Task依赖关系构建完成 size=${graph.allTasks.size()}” graph.allTasks.forEach { task -> println “${task.name}” } } }) 点击运行按钮,运行app的时候,就可以打印出 Task 任务列表
执行阶段就是根据配置阶段构建的 Task 依赖关系去执行相关的 Task。 当我们运行项目的时候,Gradle 就会根据 Task的依赖关系依次去执行相关的Task。还可以通过 gradle 命令去执行指定的 Task,如在控制台中输入如下命令,就可以执行 build 任务: ./gradlew build build 是任务名称。 ============================================================================
Gradle 提供了非常多的接口回调以便我们修改构建过程中的行为,整体流程如下图所示: 方法说明:
============================================================================ 在Gradle中,有三种方式指定task的执行顺序:
dependsOn 强依赖的方式可以细分为 静态依赖 和 动态依赖:
task提供了dependsOn,finalizedBy方法来管理task之间的依赖关系,依赖关系表达的是执行这个task时所需要依赖的其他task,也就是说这个task不能被单独执行,执行这个 Task 之前或之后需要执行另外的task。
示例代码如下所示: 静态指定依赖在定义 Task 的时候,直接为 Task 指定 dependsOn 参数,值为 另一个被依赖的 Task 的名字: task taskX { doLast{ println ‘taskX’ } } task taskY { doLast{ println ‘taskY’ } } task taskZ(dependsOn:taskX) { // 多依赖方式:dependsOn:[taskX,taskY] doLast{ println ‘taskZ’ } } // 当我们执行taskZ的时候,由于依赖了taskX,则taskX会先执行,然后才会执行:taskZ 除了在 Task 定义的时候指定 Task 的依赖之外,还可以通过 Task 的 dependsOn 方法,为 Task 指定依赖: task taskZ {// 定义Task的时候不指定依赖 doLast{ println ‘taskZ’ } } // 通过task的dependsOn方法,也可以指定task的依赖task。 taskZ.dependsOn(taskX,taskY) 当一个task依赖多个task的时候,被依赖的task之间,如果没有依赖关系的话,那么他们的执行顺序是随机的,并无影响。 动态添加依赖当 Task 在定义的时候,不知道所依赖的 Task 是什么,在配置阶段,通过条件找出符合条件的 Task ,并进行依赖。 task lib1 { doLask{ println ‘lib1’ } } task lib2 { doLask{ println ‘lib2’ } } task lib3 { doLask{ println ‘lib3’ } } // 动态指定taskX依赖所有以lib开头的task task taskX{ // 动态指定依赖 dependsOn this.tasks.findAll{ task-> return task.name.startsWidth(‘lib’) } doLast { println ‘taskZ’ } } 当一个参数作为TaskA的输出参数,同时又作为TaskB的输入参数。那么当执行TaskB的时候先要执行TaskA。即输出的Task先于输入的Task执行。 如: ext { testFile = file("${this.buildDir}/test.txt") } // 生产者 Task task producer { outputs.file testFile doLast { outputs.getFiles().singleFile.withWriter { writer -> writer.append(“我爱中国”) } println “producer Task 执行结束” } } // 消费者 Task task consumer { inputs.file testFile doLast { println “读取文件内容:${inputs.files.singleFile.text}” println “consumer Task 执行结束” } } task testTask(dependsOn: [producer, consumer]) { doLast { println “测试Task执行结束” } } 文件 testFile 是 producer 的输出参数,是 consumer 的输入参数,所以 producer 优先于 consumer 执行。 可以指定Task执行顺序的方法还有:
示例代码:
task taskA { doLast { println “taskA 执行” } } task taskB { mustRunAfter(taskA) doLast { println “taskB 执行” } } task testAB(dependsOn: [taskA, taskB]) { doLast { println “testAB 执行” } } 执行 任务:testAB,输出信息为: ? shouldRunAfter与mustRunAfter类似,这就不在测试了。
task taskA { doLast { println “taskA 执行” } } task taskB { finalizedBy(taskA) doLast { println “taskB 执行” } } task testAB(dependsOn: [taskA, taskB]) { doLast { println “testAB 执行” } } 同样的代码,就把 mustRunAfter 替换成了 finalizedBy 方法,按照finalizedBy 方法的含义,就是:taskB 执行结束后,再执行 taskA。运行 testAB 任务,输出信息为: |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 9:42:28- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |