咱們先來看一段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的大門吧。