本文来自网易云社区

作者:孙有军

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. 基于screen.width的伪响应式开发

    一.站在用户的角度看问题 一个用户,访问一个web页面的真实场景是怎样的呢? 下面是某用户访问某站点的一个场景: 1. 小明打开了自己的电脑,访问了鑫空间-鑫生活: 2. 小明体内洪荒之力无法控制,疯 ...

  2. weexpack 创建项目, 打包Android 和 ios

    1: 首先确保 node.js版本大于6.0, 不然使用 weexpack 时会报错(部分使用es6语言,node版本太低不支持es6) 下面所有都是命令行执行的命令 2: 全局安装 weexpack ...

  3. MATLAB之折线图、柱状图、饼图以及常用绘图技巧

    MATLAB之折线图.柱状图.饼图以及常用绘图技巧 一.折线图 参考代码: %图1:各模式直接成本预测 %table0-table1为1*9的数组,记录关键数据 table0 = data_modol ...

  4. GitLab关于SSH的使用

    SSH Git是分布式版本控制系统,这意味着您可以在本地工作,但您也可以将更改共享或“推送”到其他服务器.在将更改推送到GitLab服务器之前,您需要一个用于共享信息的安全通信通道. SSH协议提供此 ...

  5. Cocos2d-x v3.1 坐标系统(五)

    Cocos2d-x v3.1 坐标系统(五) 为了能够更好的布局以及了解对象所在的位置,我们必须对Cocos2d-x中的坐标有详细的了解,本篇文章主要就是了解Cocos中用到的坐标系统.学过数学的人都 ...

  6. SQLServer从其他表获取的数据更新该表的一部分

    在网上常见的是update  a  set  username  =  username  FROM b  on a.userid=b.userid,该更新语句是对a表中所有行进行更新.如果只更新一部 ...

  7. cms-详细页面-3

    1.设置上一条.下一条数据 2.使用昌言插件 3.点击链接帖子的访问数加一 1.在mapper中设置分页: <?xml version="1.0" encoding=&quo ...

  8. MovieReview—Avengers: Infinity War(复仇者联盟3:无限战争)

    Antagonist? Thanos,the central figure of the Avengers 3,antagonist. Everyone has his own ideals and ...

  9. 1.VS Code 开发C#入门 安装Dotnet core

    1. dot.net  网站 下载 .NET Core 1.0  (https://www.microsoft.com/net/download/core) 2. 打开命名提示符: 3.dotnet ...

  10. Map和Set -----JavaScript

    本文摘要:http://www.liaoxuefeng.com/ JavaScript的默认对象表示方式{}可以视为其他语言中的Map或Dictionary的数据结构,即一组键值对. 但是JavaSc ...