本文来自网易云社区

作者:孙有军

1:gradle脚本是使用groovy语言写的(DSL),groovy中有一个重要的概念闭包(Closure),Closure是一段单独的代码块,它可以接收参数,返回值,也可以被赋值给变量。eg:

//无参数def Closure1 = { println 'Hello world' }
Closure1()// 执行闭包,输出Hello world//一个参数def Closure2 = { String str -> println str }//如果只有一个参数可以用it代替,写作def Closure2 = {println it}Closure2('Hello world')// 执行闭包,输出Hello world//多个参数def Closure3 = { String str,int n -> println “$str : $n" }//也可以写作 {str,n -> println “$str : $n" }
Closure3('Hello world’, 1)// 执行闭包,输出Hello world : 1 //使用变量
def var=“Hello world"
def Closure4 = { println var }//也可以写作 {str,n -> println “$str : $n" }
Closure4()// 执行闭包,输出Hello world //改变上下文
def Closure5 = {println Var} //这时还不存在 
MyClass m = new MyClass()
Closure5.setDelegate(m)// 改变上下文,这时Var已经有了,在执行之前改变了,
Closure5()//执行闭包,输出Hello world class MyClass {
    def Var = 'Hello world'
}

把closure当做参数传递
closure的好处就是可以传递给不同的方法,这样可以帮助我们解耦执行逻辑。前面的例子中已经展示了如何把closure传递给一个类的实例。下面我们将看一下各种接收closure作为参数的方法:

1.只接收一个参数,且参数是closure的方法: myMethod(myClosure)
2.如果方法只接收一个参数,括号可以省略: myMethod myClosure
3.可以使用内联的closure: myMethod {println ‘Hello World’}
4.接收两个参数的方法: myMethod(arg1, myClosure)
5.和4类似,单数closure是内联的: myMethod(arg1, { println ‘Hello World’ })
6.如果最后一个参数是closure,它可以从小括号从拿出来: myMethod(arg1) { println‘Hello World’ }

  1. Android中使用

buildscript { //  等同 def buildscript(Closure closure),?? buildscript直接使用,那是在什么地方定义的?
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
}

方法都是在Project中定义的,构建脚本顶层的语句块都会被委托给Project的实例,eg:  在Project中buildcript的定义:

  /**
     * <p>Configures the build script classpath for this project.
     *
     * <p>The given closure is executed against this project's {@link ScriptHandler}. The {@link ScriptHandler} is
     * passed to the closure as the closure's delegate.
     *
     * @param configureClosure the closure to use to configure the build script classpath.
     */
    void buildscript(Closure configureClosure);

上面可以看到repositories在ScriptHandler中执行,在ScriptHandler中又委托到RepositoryHandler。

3: task 有两个生命周期,配置阶段和执行阶段,gradle在执行task时,都会先对task进行配置,task中最顶层的代码就是配置代码,在配置阶段执行,其他代码实在执行阶段执行的。eg:

task Task1{println “hello” // 这段代码是在gradle配置阶段执行的}

task Task2{
def name =“hello”// 这段代码是在gradle配置阶段执行的doLast{println name // 这段代码是在gradle执行阶段执行的}
} task Task3 << {// << 语法糖,相当于doLast,因此整个代码都是在执行阶段执行的println name // 这段代码是在gradle执行阶段执行的}

4:task执行顺序
dependsOn: TaskB 依赖TaskA, TaskB.dependsOn TaskA 这样每次执行B都会先执行A,下面是相同的写法

task A << {println 'Hello from A'}
task B {    dependsOn A
    doLast {        println 'Hello from B'  
    }
}

同理也可以改变已有的依赖顺序,直接改变dependsOn,也可以同时依赖多个任务。

mustRunAfter: 有A B C三个task, C依赖于A,B,但A,B不相互依赖,如果要保证每次执行时A都在B之前执行,可以写作

task A << {println 'A'}
task B << {println 'B'}
task C << {println 'C'} C.dependsOn A
C.dependsOn B
B.mustRunAfter A

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 // 执行这个就可以合并了。// 下面这种方式等价于上面这种tests.dependsOn unit
tests.dependsOn ui
ui.mustRunAfter unit
mergeReports.dependsOn tests

tests.finalizedBy mergeReports// 执行tests就能合并了。表示tests执行完成后,在执行mergeReports

网易云免费体验馆,0成本体验20+款云产品!

更多网易研发、产品、运营经验分享请访问网易云社区

相关文章:
【推荐】 一个接口的性能问题定位和分析过程
【推荐】 SpringBoot入门(二)——起步依赖
【推荐】 浅谈代码结构的设计

Gradle task的更多相关文章

  1. Gradle task简单使用

    还望支持个人博客站:http://www.enjoytoday.cn task是什么 task是gradle构建脚本的最小运行单元,我们通过在gradle脚本中创建task任务,以期完成某个特定的功能 ...

  2. AndroidTest工程的自定义gradle task

    由于需要将assets目录的资源拷贝到设备sdcard中,然而我的工程是一个android test工程,而android test工程在编译阶段,不会把assets目录的资源打包成对应apk,而为了 ...

  3. flutter 卡在Running Gradle task 'assembleDebug'...

    Android项目运行时出错 卡在Initializing gradle… 运行时会卡在Initializing gradle..., 此时因为Android项目会用到Gradle, 如果没有FQ,下 ...

  4. [Android Tips] 23. How to fail/stop Gradle task immediately if some conditions are not met

    throw new GradleException("conditions are not met") 参考 How to fail/stop task immediately i ...

  5. Android Gradle Task

    Tasks runnable from root project ------------------------------------------------------------ Androi ...

  6. Gradle Goodness: Rename Ant Task Names When Importing Ant Build File

    Migrating from Ant to Gradle is very easy with the importBuild method from AntBuilder. We only have ...

  7. Android Gradle 自定义Task 详解

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/76408024 本文出自[赵彦军的博客] 一:Gradle 是什么 Gradle是一 ...

  8. Gradle 使用教程之 Task 详解

    最近打算学习下 gradle 在 Android 中的使用,结果百度出来的文章都是介绍性文章,没啥干货.后来找到 gradle 官网教程,自己对着撸. Gradle 概述: Gradle 是一个基于 ...

  9. Gradle之Android Gradle Plugin 主要 Task 分析(三)

    [Android 修炼手册]Gradle 篇 -- Android Gradle Plugin 主要 Task 分析 预备知识 理解 gradle 的基本开发 了解 gradle task 和 plu ...

随机推荐

  1. 对CSRF的理解及防范

    对CSRF的理解: 假定a是一个银行网站, b是一个危险网站. 当用户在访问a, 并且session并未结束的情况下, 去访问b网站, b网站就可以通过隐藏的url或者是表单来伪造用户对a的get或者 ...

  2. 第6章 传输层(详解TCP的三次握手与四次挥手)

    第6章 传输层 传输层简介 传输层为网络应用程序提供了一个接口,并且能够对网络传输提供了可选的错误检测.流量控制和验证功能.TCP/IP传输层包含很多有用的协议,能够提供数据在网络传输所需的必要寻址信 ...

  3. JSP对象和JavaBean

    1. JSP 客户端请求 当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信息头的一部分来传送的,如下图所示: Http请求头对应的内容如下: 对应方 ...

  4. Paoding-Rose学习

    * HttpServletRequest.getContextPath 获取web程序root.如果是默认位置,返回””空串,否则返回 /根路径名 * rose是如何扫描到资源的 利用spring提供 ...

  5. python3基础11(正则表达式及re模块)

    #生成re对象 compile# 之后再期调用 match search 返回匹配到的字符串# findall 返回匹配结果的列表#如果要对匹配的结果进行分组,可加(),并可通过\数字 去应用

  6. jquery实现简单的验证码倒计时的效果

    HTML: <div class="container"> <form> <div class="form-group"> ...

  7. javascript:理解try...catch...finally

    以前,我一直喜欢用console.log(do some thing)去执行输出的类型和值,想马上看到弹出的信息,就会直接在浏览器alert()一下,这些是基础知识. 稍微复杂一点点,就要用到判断语句 ...

  8. 如何解析比特币中的交易原始数据rawData

    交易数据结构 有关交易的详细信息可以查看比特币的wiki网站:Transaction TxBinaryMap: 原始图片地址 交易的结构表格(Transaction): 示例数据 以一个正式网络的一笔 ...

  9. java—三大框架详解,其发展过程及掌握的Java技术慨括

    Struts.Hibernate和Spring是我们Java开发中的常用关键,他们分别针对不同的应用场景给出最合适的解决方案.但你是否知道,这些知名框架最初是怎样产生的? 我们知道,传统的Java W ...

  10. hdu-2112 HDU Today---dijkstra+标号

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2112. 题目大意: 求起点到终点的最短路 解题思路: 对地名进行编号即可 然后直接dijkstra算 ...