写出gradle风格的groovy代码

写出gradle风格的groovy代码

咱们先来看一段gradle中的代码:java

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.10'
}

我第一次看gradle代码的时候是懵逼的,android

这是哪门子语言,这究竟是相似xml的标记语言仍是相似java的语言?我不懂。不懂不要紧,学了就懂了嘛。闭包

你们如今已经知道了gradle使用groovy写的,因此他是我前面说的相似java的语言,但他是如何作到像上面这样炫酷吊炸天的写法呢?咱们接下分析一下:app

首先你在gradle中看不到;这是由于groovy支持不写;学习

println 'hello world'

下面咱们看看这个:gradle

dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'
    }

这个放在groovy中怎么解读呢?首先咱们须要知道的是groovy中方法调用时能够省略()的!!!对你没有看错,正如上面的println 'hello world',ok,那不难理解上面的dependencies是一个方法名了,这里是一个方法的调用,而不是方法的定义。既然是方法的调用,那就能够知道{}实际上就是一个groovy的闭包类型的参数。而这个闭包里面又是个classpath的方法调用。ui

既然上面被我说通了,那就写个例子试试吧:spa

def dependencies(Closure cl){
    cl.call();
}

def classpath(String path){
    println path
}

dependencies {
    classpath 'com.android.tools.build:gradle:2.1.2'
}

Look,代码运行正常。code

那么咱们再来看这个:xml

task clean(type: Delete) {
    delete rootProject.buildDir
}

这个用上面的思路套进去看看呢?task是一个方法,没毛病。后面是两个参数?clean和一个闭包?这里就不对了,若是是两个参数,中间须要有,隔开,因此这里只有一个参数,就是clean。那这就是什么写法?这里咱们又要了解groovy中的一个语法特性,

当一个方法的最后一个参数是闭包,能够将这个闭包写在()外面。

看例子:

def foo(String s,Closure cl){
    cl(s)
}

//❶
foo('hello world'){
    println it
}

foo 'hello world',{
    println it
}

方法的两种特殊写法都在这了,上面讲个写法就是❶处的写法。

因此把clean理解为一个参数是对的,接着再看clean(type: Delete)这个就简单了,groovy中的方法参数是支持命名参数的,这里用的就是命名参数,到这里都理顺了,咱们仍是写一个小例子模仿一下上面的写法:

def task(String taskName){
    println 'execute task ' + taskName
}

def clean(Map type,Closure cl){
    type.type
}

def delete(String path){

}

Delete = 'delete'

task clean(type:Delete){
    delete "path"
}

这里我很勉强的写出了相似的代码,但gradle中的这些写法真的是咱们理解的这样子吗?咱们使用代码跟踪来看看.

首先看看dependencies是否是一个方法?

void dependencies(Closure var1);

哈哈,还真是的,并且参数的确是一个闭包。

那在看看classpath是否是一个方法?

WTF,见鬼了,跟踪classpath的结果以下:

Dependency add(String configurationName, Object dependencyNotation);

居然跟踪到了这个add方法,并且add方法还有两个参数,这是什么鬼?更诡异的是这个add方法属于DependencyHandler.java这个接口,对你没看错,是java接口。What the hell???

冷静一下。。。

咱们分析一下,为何会发生这种事情,这个难道已经超出咱们认知的方位了?其实否则,虽然如今我也是啥都不知道,但我以为这其中的起因必定可以在gradle中找到,因此就然咱们正式开启学习gradle的大门吧。

相关文章
相关标签/搜索