寫出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的大門吧。

相關文章
相關標籤/搜索