以下groovy语法的真正含义是什么?
Gradle文档讲述了build.gradle如何只是 groovy。 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'])
}
答案 0 :(得分:5)
您可以将gradle构建脚本视为一些委托给对象的代码,该对象可以响应写入其中的方法调用。
该脚本使用了大量的Groovy语法糖,因此删除它们应该如下所示:
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']]) );
});
所以脚本实际上是一堆方法调用:
def apply(Map)
def android(Closure)
def dependencies(Closure)
这个android(Closure)
将收到一个闭包,并将其中调用的方法委托给一个可以响应这些方法的对象:
def compileSdkVersion(Integer)
def buildToolsVersion(String)
...
鉴于此,我们可以解析脚本,将其委托给某个对象,然后执行它。
使用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:
中
- 命令链
醇>Groovy允许您省略围绕顶级语句的方法调用的参数的括号。 “命令链”功能通过允许我们链接这种无括号的方法调用来扩展它,既不需要围绕参数的括号,也不需要链接调用之间的点。
还有Groovy ConfigSlurper
,但我不确定它是否可以像Gradle想要的那样。
答案 1 :(得分:3)
感谢AndroidGuy为我提供了以下信息的优秀视频。视频长达35分钟,所以这里是TL; DR。
此语法大多数是method次调用和closures的混合。闭包用花括号表示。另请注意,方法调用不需要括号。
apply plugin: 'com.android.application'
这是使用单个命名参数“plugin”调用apply对象上的project方法。项目对象是Gradle提供的顶级对象。
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
这是设置项目对象的dependencies属性。 Groovy properties基本上是getter和setter的简写。 dependencies属性是一个委托给DependencyHandler的Closure对象。 Groovy delegation本质上是一种增加闭包范围解析的方法。依赖关系包含一个用于编译的单个方法调用,它接受一个FileTree位置参数。 FileTree由项目对象中定义的fileTree方法生成。编译方法对我来说仍然有点模糊。它似乎来自Java plugin,但没有明确记录在那里。 “编译”部分对我来说仍然有点神奇。
android {
...
}
我将把'android'部分作为练习留给读者。网络上没有Android Gradle域特定语言(DSL)。你必须download it。