[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,这有利于 我们针对性的推广. ...
随机推荐
- cf.301.D. Bad Luck Island(dp + probabilities)
D. Bad Luck Island time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Hadoop 之面试题
颜色区别: 蓝色:hive,橙色:Hbase.黑色hadoop 请简述hadoop怎样实现二级排序. 你认为用Java,Streaming,pipe 方式开发map/reduce,各有哪些优缺点: 6 ...
- 重读C#委托、事件有感
去年学习C#的时候按照进度把C#的委托和事件“认真”的学习了一下,自己知道委托和事件的重要性,所以也努力的学习,可说实也没怎么学懂.碰巧这段时间在做一个解析GPS数据的小项目,因为其中有需要条件自动判 ...
- 【C语言入门教程】4.5 指针变量的定义与引用
指针变量是包含内存地址的变量.一般的变量直接包含一个特定的值,而指针变量包含的是某一特定数据类型的内存地址.普通变量直接引用其中的值,指针变量则间接引用所指向内存地址中的值.指针变量在使用前需要声明与 ...
- SEO 百度后台主动推送链接
实践步骤,先用爬虫程序将本网站的所有连接爬取出来,再用python文件处理程序把爬虫来的东东整理成一行一个链接的文本格式.再用postman接口测试工具,使用post方式,将所有的链接post过去,这 ...
- objective-c-sort-keys-of-nsdictionary-based-on-dictionary-entries
NSArray *keys = [someDictionary allKeys]; NSArray *sortedKeys = [keys sortedArrayUsingComparator:^NS ...
- div动态显示iframe内容
在div里隐藏不了iframe <div id="popupmenu" style="position:relative; display:none; z-inde ...
- ubutu之mysql emma中文乱码问题解决
emma默认用apt-get 安装的话,emma是不支持中文的,配置文件或直接修改emma程序源文件(python).apt-get安装emmasudo apt-get install emma ...
- css3 github javascript
欢迎关注我的 github github博客地址 github地址
- Effective Java 读书笔记之一 创建和销毁对象
一.考虑用静态工厂方法代替构造器 这里的静态工厂方法是指类中使用public static 修饰的方法,和设计模式的工厂方法模式没有任何关系.相对于使用共有的构造器来创建对象,静态工厂方法有几大优势: ...