Gradle Task基本知识

来源:互联网 发布:前端页面性能优化 编辑:程序博客网 时间:2024/06/02 06:56

       接上一篇文章,我们继续来学校Gradle的知识,本文内容是参考http://android.jobbole.com/81485/整理得来的。

基础知识

       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 worldclass 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’ }

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。

生命周期

       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执行阶段执行的}

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

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

总结

       这里只是初步总结了gradle的基本知识,实际还有很多东西需要学习。后续继续对android中使用进行解析。

1 0
原创粉丝点击