2015-04-06 31 views
5

以下groovy語法的真正含義是什麼?請解釋Android build.gradle groovy語法

Gradle docs嘟嘟build.gradle是如何只是常規。 Android團隊已經將默認的build.gradle簡化爲它看起來不像代碼(至少對我來說)。請根據groovy語法解釋這是做什麼的。例如,Android插件使用這些全局變量聲明?

如果您在說明中包含對http://groovy-lang.org/syntax.html的引用,則可獲得獎勵積分。

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 21 
    buildToolsVersion "21.1.2" 

    defaultConfig { 
     applicationId "com.crittercism" 
     minSdkVersion 15 
     targetSdkVersion 21 
     versionCode 5 
     versionName "5.0" 
    } 

} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
} 

回答

3

感謝AndroidGuy提供的優秀視頻,通知我下面的信息。該視頻長35分鐘,所以這裏是TL; DR。

大部分語法是method調用和closures的混合。關閉由花括號表示。另請注意,方法調用不需要括號。

apply plugin: 'com.android.application' 

這是調用與單個命名參數「插件」的project對象上的apply方法。項目對象是Gradle提供的頂級對象。

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
} 

這是設置項目對象的dependencies屬性。 Groovy properties基本上是獲取者和制定者的簡寫。依賴項屬性是一個代表DependencyHandler的Closure對象。本質上是一種增加封閉範圍解決方案的方法。依賴關係closure包含一個要編譯的方法調用,它需要FileTree位置參數。 FileTree由在項目對象中定義的fileTree方法生成。編譯方法對我來說仍然有點模糊。它似乎來自Java plugin,但它沒有明確記錄在那裏。 '編譯'部分對我來說仍然有點神奇。

android { 
    ... 
} 

我將「android」部分作爲練習留給讀者。 Android Gradle域專用語言(DSL)在網絡上不可用。你必須download it

5

你可以把gradle這個構建腳本的一些代碼這是委託給一個對象,它可以響應寫入其中的方法調用

該腳本使用了大量的Groovy的語法糖,所以去除它們,就應該是這樣的:

所以劇本真的是一堆方法的調用:

  • def apply(Map)
  • def android(Closure)
  • def dependencies(Closure)

android(Closure)將接收封閉,並會委託調用它的方法,以一個對象,它可以對這些方法作出迴應:鑑於

  • def compileSdkVersion(Integer)
  • def buildToolsVersion(String)
  • ...

那我們可以解析這個腳本,把它委託給一些對象和t母雞執行它。

使用DelegatingBaseScript進行委託是完成它的一種方法(不確定Gradle是這樣做的)。這裏是一個簡單化的工作版本:

import org.codehaus.groovy.control.CompilerConfiguration 

gradleScript = ''' 
apply plugin: 'com.android.application' 

android({ 
    compileSdkVersion(21) 
    buildToolsVersion("21.1.2") 
})''' 


class PocketGradle { 
    def config = [apply:[]].withDefault { [:] } 

    def apply(map) { 
    config.apply << map.plugin 
    } 

    def android(Closure closure) { 
    closure.delegate = new Expando(
     compileSdkVersion: { Integer version -> 
      config.android.compileSdkVersion = version 
     }, 
     buildToolsVersion : { String version -> 
      config.android.buildToolsVersion = version 
     }, 
    ) 
    closure() 
    } 
} 

def compiler = new CompilerConfiguration(scriptBaseClass: DelegatingScript.class.name) 

shell = new GroovyShell(this.class.classLoader, new Binding(), compiler) 

script = shell.parse gradleScript 
script.setDelegate(gradle = new PocketGradle()) 
script.run() 

assert gradle.config == [ 
    apply: ['com.android.application'], 
    android: [ 
    compileSdkVersion: 21, 
    buildToolsVersion: '21.1.2' 
    ] 
] 

可以在Groovy Web Console執行腳本(單擊「控制檯編輯」,然後「執行腳本」)。

大部分的語法解釋是在DSL section

  1. 命令鏈

Groovy中,您可以省略圍繞一個方法調用中的頂級語句的參數括號。 「命令鏈」功能通過允許我們鏈接這種無括號的方法調用來擴展這一功能,在鏈接調用之間既不需要括號,也不需要點。

還有Groovy ConfigSlurper,但我不確定它是否可以像Gradle一樣想要。