[Android Pro] Gradle tip #3-Task顺序
reference to : http://blog.csdn.net/lzyzsd/article/details/46935405
我注意到我在使用Gradle的时候遇到的大多数问题都是和task的执行顺序有关的。很明显如果我的构建会工作的更好如果我的task都是在正确的时候执行。下面我们就深入了解一下如何更改task的执行顺序。
dependsOn
我认为最直接的方式来说明的你task的执行时依赖别的task的方法就是使用dependsOn方法。
比如下面的场景,已经存在task A,我们要添加一个task B,它的执行必须要在A执行完之后:
这是一个很简单的场景,假定A和B的定义如下:
task A << {println 'Hello from A'}
task B << {println 'Hello from B'}
只需要简单的调用B.dependsOn A,就可以了。
这意味着,只要我执行task B,task A都会先执行。
paveldudka$ gradle B
:A
Hello from A
:B
Hello from B
另外,你也可以在task的配置区中来声明它的依赖:
task A << {println 'Hello from A'}
task B {
dependsOn A
doLast {
println 'Hello from B'
}
}
如果我们想要在已经存在的task依赖中插入我们的task该怎么做呢?
过程和刚才类似。假定已经存在如下的task依赖:
task A << {println 'Hello from A'}
task B << {println 'Hello from B'}
task C << {println 'Hello from C'}
B.dependsOn A
C.dependsOn B
加入我们的新的task
task B1 << {println 'Hello from B1'}
B1.dependsOn B
C.dependsOn B1
输出:
paveldudka$ gradle C
:A
Hello from A
:B
Hello from B
:B1
Hello from B1
:C
Hello from C
注意dependsOn把task添加到依赖的集合中,所以依赖多个task是没有问题的。

task B1 << {println 'Hello from B1'}
B1.dependsOn B
B1.dependsOn Q
输出:
paveldudka$ gradle B1
:A
Hello from A
:B
Hello from B
:Q
Hello from Q
:B1
Hello from B1
mustRunAfter
现在假定我又一个task,它依赖于其他两个task。这里我使用一个真实的场景,我有两个task,一个单元测试的task,一个是UI测试的task。另外还有一个task是跑所有的测试的,它依赖于前面的两个task。

task unit << {println 'Hello from unit tests'}
task ui << {println 'Hello from UI tests'}
task tests << {println 'Hello from all tests!'}
tests.dependsOn unit
tests.dependsOn ui
输出:
paveldudka$ gradle tests
:ui
Hello from UI tests
:unit
Hello from unit tests
:tests
Hello from all tests!
尽管unitest和UI test会子啊test task之前执行,但是unit和ui这两个task的执行顺序是不能保证的。虽然现在来看是按照字母表的顺序执行,但这是依赖于Gradle的实现的,你的代码中绝对不能依赖这种顺序。
由于UI测试时间远比unit test时间长,因此我希望unit test先执行。一个解决办法就是让ui task依赖于unit task。

task unit << {println 'Hello from unit tests'}
task ui << {println 'Hello from UI tests'}
task tests << {println 'Hello from all tests!'}
tests.dependsOn unit
tests.dependsOn ui
ui.dependsOn unit // <-- I added this dependency
输出:
paveldudka$ gradle tests
:unit
Hello from unit tests
:ui
Hello from UI tests
:tests
Hello from all tests!
现在unit test会在ui test之前执行了。
但是这里有个很恶心的问题,我的ui测试其实并不依赖于unit test。我希望能够单独的执行ui test,但是这里每次我执行ui test,都会先执行unit test。
这里就要用到mustRunAfter了。
mustRunAfter并不会添加依赖,它只是告诉Gradle执行的优先级如果两个task同时存在。比如我们这里就可以指定
ui.mustRunAfter unit,这样如果ui task和unit task同时存在,Gradle会先执行unit
test,而如果只执行gradle ui,并不会去执行unit task。
task unit << {println 'Hello from unit tests'}
task ui << {println 'Hello from UI tests'}
task tests << {println 'Hello from all tests!'}
tests.dependsOn unit
tests.dependsOn ui
ui.mustRunAfter unit
输出:
paveldudka$ gradle tests
:unit
Hello from unit tests
:ui
Hello from UI tests
:tests
Hello from all tests!
依赖关系如下图:

mustRunAfter在Gradle2.4中目前还是实验性的功能。
finalizedBy
现在我们已经有两个task,unit和ui,假定这两个task都会输出测试报告,现在我想把这两个测试报告合并成一个:

task unit << {println 'Hello from unit tests'}
task ui << {println 'Hello from UI tests'}
task tests << {println 'Hello from all tests!'}
task mergeReports << {println 'Merging test reports'}
tests.dependsOn unit
tests.dependsOn ui
ui.mustRunAfter unit
mergeReports.dependsOn tests
现在如果我想获得ui和unit的测试报告,执行task mergeReports就可以了。
paveldudka$ gradle mergeReports
:unit
Hello from unit tests
:ui
Hello from UI tests
:tests
Hello from all tests!
:mergeReports
Merging test reports
这个task是能工作,但是看起来好笨啊。mergeReports从用户的角度来看感觉不是特别好。我希望执行tests task就可以获得测试报告,而不必知道mergeReports的存在。当然我可以把merge的逻辑挪到tests task中,但我不想把tests task搞的太臃肿,我还是继续把merge的逻辑放在mergeReports task中。
finalizeBy来救场了。顾名思义,finalizeBy就是在task执行完之后要执行的task。修改我们的脚本如下:
task unit << {println 'Hello from unit tests'}
task ui << {println 'Hello from UI tests'}
task tests << {println 'Hello from all tests!'}
task mergeReports << {println 'Merging test reports'}
tests.dependsOn unit
tests.dependsOn ui
ui.mustRunAfter unit
mergeReports.dependsOn tests
tests.finalizedBy mergeReports
现在执行tests task就可以拿到测试报告了:
paveldudka$ gradle tests
:unit
Hello from unit tests
:ui
Hello from UI tests
:tests
Hello from all tests!
:mergeReports
Merging test reports
注意,finalizedBy也是Gradle2.4的实验性功能
[Android Pro] Gradle tip #3-Task顺序的更多相关文章
- [Android Pro] Gradle Tips#1-tasks
reference to : http://trickyandroid.com/gradle-tip-1-tasks/ http://blog.csdn.net/lzyzsd/article/deta ...
- [Android Pro] Gradle Tips#2-语法
referece to : http://blog.csdn.net/lzyzsd/article/details/46935063 在第一篇博客中,我讲解了关于tasks和构建过程中task的不同阶 ...
- Gradle之Android Gradle Plugin 主要 Task 分析(三)
[Android 修炼手册]Gradle 篇 -- Android Gradle Plugin 主要 Task 分析 预备知识 理解 gradle 的基本开发 了解 gradle task 和 plu ...
- 深入理解Android之Gradle
深入理解Android之Gradle 格式更加精美的PDF版请到:http://vdisk.weibo.com/s/z68f8l0xTYrZt 下载 Gradle是当前非常"劲爆" ...
- Android studio gradle配置!!!【转】
转自:http://www.open-open.com/lib/view/open1415793464648.html Gradle 基本概念 首先我们学习几个gradle 的脚本语法,掌握了这几个语 ...
- Android studio gradle配置完整版(转)
Android studio gradle配置完整版https://my.oschina.net/u/1471093/blog/539075 Android studio 自定义打包apk名 - pe ...
- Android使用Gradle命令动态传参完成打包,不需要修改代码
不得不说,Gradle很强大,有人会问Gradle是什么?这里也不细讲,在我认为他就是一个构建神器.Gradle 提供了: 一个像 Ant 一样的非常灵活的通用构建工具 一种可切换的, 像 Maven ...
- Android Studio] Gradle项目中添加JNI生成文件(.so文件)
转:http://blog.csdn.net/qiujuer/article/details/24209457 为了适应潮流使用Android Studio还是有半年多了! 对于从Eclipse迁移项 ...
- Android studio gradle 打包 那些事
总结了一下 目前觉得比较好用的gradle 和一些打包 经验.放在这里. 首先说下 渠道号 这个概念,我们经常会统计我们的api 访问来源 是来自于那个app store,这有利于 我们针对性的推广. ...
随机推荐
- 输入三个数a,b,c,要示按由小到大的顺序输出
#include<stdio.h>int main(){ double a,b,c,t; scanf("%lf %lf %lf",&a, ...
- 将Centos的yum源更换为阿里云源
阿里云Linux安装软件镜像源 阿里云是最近新出的一个镜像源.得益与阿里云的高速发展,这么大的需求,肯定会推出自己的镜像源.阿里云Linux安装镜像源地址:http://mirrors.aliyun. ...
- 大型网站SEO优化策略框架
- 题目1373:整数中1出现的次数(从1到n整数中1出现的次数)
题目1373:整数中1出现的次数(从1到n整数中1出现的次数) 题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU发来求助信,希望亲们能帮帮他 ...
- jquery版悬浮模块demo
在做在线客服时,代码就是按照该模块命名.现在,我要添加一个返回主页的功能,我觉得再复制一遍之前的代码,那个量有点多,如果我再添加一个功能,那个量会很多……现在我用创建对象字面量的方式来创建(其实我还想 ...
- 读书笔记-String
[String]就是对char[]数组进行封装的对象,由三部分组成: 1, char数组:它是String对象所表示的字符串的超集: 2, 3, offset和count,表示了String对象表示的 ...
- echarts
ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏览器(IE6/7/8/9/10/11 ...
- ubuntu 14.04 对exfat的支持
sudo apt-get install exfat-utils exfat-fuse sudo reboot
- Tomcat部署Web应用的两种方式
WEB工程目录结构 部署方式一:此种方式部署,jsp页面修改后,不能动态更新,需要重新部署才能看到效果.不过可以配置动态更新实现. 部署方式二:此种方式部署,jsp修改后,直接在页面可以看到效果.(因 ...
- mysql中表名是order的CRUD的错误
org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: com.mysql.jdbc. ...