上一篇博客中,我们简单的利用Gradle从零开始构建了一个简单的Android app项目,对build.gradle中的有些语法,可能不是很熟悉,所以很有必要理解Gradle的重要语法。通过这边文章,希望能读懂简单build,gradle,最重要的是如何查阅文档。
‘’,“”,’‘’ ‘’‘
看gradle脚本的时候,发现有的字符串是’’,有的是“”,还有的是’’’ ‘’’ 他们都用在什么地方呢?
单引号’’中的内容严格对应Java中的String,不对$符号进行转义。
双引号””的内容则和脚本语言的处理有点像,如果字符中有号的话,则它会
号的话,则它会表达式先求值。例如:
号的话,则它会表达式先求值。例如:
1 2 | def x = 1 defdoubleQuoteWithDollar = "I am $x dolloar" //输出I am 1 dolloar |
闭包Closures
Gradle脚本是利用Groovy语言编写的,而Groovy语言又是对java语言的扩展,使其可以像脚本一样运行,而不需要编译。Gradle脚本中最晦涩的莫过于Groovy中的闭包了。
什么是闭包
Closure是一段单独的代码块,它可以接收参数,返回值,也可以被赋值给变量。其实Groovy的闭包更象是一个“方法指针”,代码在某处被定义,但不执行,然后在其后的调用处执行。
闭包格式
下面是一个闭包的简单例子:
def myClosure = { println 'Hello world!' } /*执行*/ myClosure() //执行结果: Hello world! |
def myClosure = {println 'hello world' } myClosure() //执行结果: Hello world! |
如果Closure只接收一个参数,可以使用it来引用这个参数:
def myClosure = {println it } myClosure('Hello world!') //执行结果: Hello world! |
接收多个参数的Closure:可以不指定参数类型
def myClosure = {str, num -> println "$str : $num" } myClosure('my string', 21) //执行结果: my string : 21 |
可以使用当前上下文中的变量:
def myVar = 'Hello World!' def myClosure = {println myVar} myClosure() //执行结果: Hello world! |
def myClosure = {println myVar} //I'm referencing myVar from MyClass class MyClass m = new MyClass() myClosure.setDelegate(m) myClosure() class MyClass { def myVar = 'Hello from MyClass!' } //执行结果: Hello from MyClass! |
在创建closure的时候,myVar并不存在。这并没有什么问题,因为当我们执行closure的时候,在closure的上下文中,myVar是存在的.
## 闭包做参数
1.只接收一个参数,且参数是closure的方法: myMethod(myClosure)
2.如果方法只接收一个参数,括号可以省略: myMethod myClosure
3.可以使用内联的closure: myMethod {println ‘Hello World’}
4.接收两个参数的方法: myMethod(arg1, myClosure)
5.和4类似,单数closure是内联的: myMethod(arg1, { println ‘Hello World’ })
6.如果最后一个参数是closure,它可以从小括号从拿出来: myMethod(arg1) { println ‘Hello World’ }
Gradle脚本中大量使用了2.3.6所示的写法。
build.gradle中的相关解释
上一篇博客中build.gradle的相关片段如下
buildscript{ println '------buildscript configire phase---------' repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.0' } } |
现在应该很好理解了吧,buildscript就是一个以闭包为参数的方法,省略了(),而且使用了内联闭包,参考上面的方法3。
现在还有一个疑问buildscript方法是谁定义的?
查阅Gradle DSL文档(可参考第一篇博客中的方法获取相关文档)docs/dsl/index.html,如下图所示
可知buildscript委托给了project实现,仔细查看了该文档,未发现 android方法,那么它是怎么来的呢?
别忘记了,前面还引入了一个插件
apply plugin: 'com.android.application'
android 方法应该是由他提供的了。但是我在文档中也没找到android方法,很奇怪。从他的用法上看,是接受了一个闭包作为其唯一参数。而且这个闭包的上下文被设置为了AppExtension。其文档android-gradle-plugin-dsl/com.android.build.gradle.AppExtension.html,如下图所示