目录
一 前言
二 Groovy基础语法
2.1 变量和方法
2.2 Groovy的数据类型
2.2.1 String
2.2.2 Closure(闭包)
2.2.3 List和Map
2.2.4 List和Map
三 Groovy中的类
一 前言
Gradle官网
官方文档,可当做字典查阅
Gradle是Android的构建工具,AndroidStudio的build是通过Gradle来实现的。不少安卓领域的技术如:插件化、热修复、构建系统等,都需要借助Gradle完成。
Groovy是一门jvm语言,功能强大细节多,全部学习收益小。作为一门DSL(特定领域语言)语言,只限于某个特定领域使用,可以理解成Gradle是用groovy语言实现的一个框架。
学习Gradle主要需要掌握下面三种语言
Groovy语言
Gradle DSL
Android DSL
Groovy的优势:作为一门jvm语言,最终编译成class文件然后在jvm上执行,支持所有Java的特性,完全可以混写Java和Groovy,不同点可参考 文档,不需要过分纠结;Groovy提供了更加灵活简单的语法、大量的语法糖以及闭包特性。学习也可部分参考 W3School快速预览了解,或者阅读下面的基础语法进行大体掌握。
既然Gradle是用groovy语言实现的,下面我们自然要先学习groovy的基本语法。
二 Groovy基础语法
2.1 变量和方法
变量和fang均使用def 关键字声明:
def int a = 1;
def String b = “hello world”;
def int hello() {
println (“hello world”);
return 1;
}
1.
2.
3.
4.
5.
6.
7.
现在我们如何执行这一段Groovy代码呢?当然我们可以在 官网下载地址下载最新的gradle版本,解压、安装、添加环境变量…
但是作安卓开发者而言,或许更方便的选择是利用Android Studio中已有的环境,快速地测试代码。
打开Andriod Studio的某个项目,在Gradle Scripts目录下打开项目的build.gradle,将下面一段代码粘贴到文件末尾:
task(myGroovyTestFun).doLast {
println “start execute myGroovyTestFun”
println hello()
}
def int a = 1;
def String b = “hello world”;
def int hello() {
println (“hello world”);
return 1;
}
此刻打开Andriod Studio的Terminal,输入命令:
./gradlew myGroovyTestFun
1.
这样就可以方便快速地运行我们的groovy代码,结果如下:
> Task :myGroovyTestFun
start execute myGroovyTestFun
hello world
是不是很方便!
我们回顾下上面的变量和方法的写法,是不是和java几乎没有区别,只不过多了def关键字!
对,但是相比java,Groovy中有很多东西可以省略:
分号可省略
变量的类型、方法的返回值可省略
方法调用时,括号可省略
方法中的return可省略
方法的返回类型可省略
方法有返回类型,def关键字可省略
基于以上的原则,上面的代码可以写成如下形式:
def a = 1;
def b = “hello world”; // 省略变量类型
// 省略def、println省略括号
int hello() {
println “hello world”;
return 1;
}
注意:Groovy类型可以动态推断,但Groovy仍是强类型的语言,类型不匹配会报错;
2.2 Groovy的数据类型
在Groovy中,数据类型有:
Java中的基本数据类型和对象
Closure(闭包)
加强的List、Map等集合类型
加强的File、Stream等IO类型
基本数据类型和对象和Java中的一致,只不过Gradle中的对象默认的修饰符为public。
类型可以显示声明:
String b = “hello world”
1.
也可以用 def 来声明,用 def 声明的类型Groovy将会进行类型推断。
def b = “hello world”
1.
下面主要说下String、闭包、集合和IO等。
2.2.1 String
String的特色在于字符串的拼接,比如:
task(myGroovyTestFun).doLast {
println “start execute myGroovyTestFun”
hello()
}
def hello() {
def a = 1
def b = “hello world”
def c = “a=${a}, b=${b}”
println c
}
输出:
> Task :myGroovyTestFun
start execute myGroovyTestFun
a=1, b=hello world
1.
2.
3.
2.2.2 Closure(闭包)
Groovy中闭包是一种特殊的数据类型,闭包可以作为一个变量、一个方法的参数or返回值。
如何声明闭包?
{ parameters ->
code
}
1.
2.
3.
闭包可以有返回值和参数,当然也可以没有。举例:
def test1 = { int a, String b ->
println “a=${a}, b=${b}, I am a closure!”
}
// 这里省略了闭包的参数类型
def test2 = { a, b ->
println “a=${a}, b=${b}, I am a closure!”
}
def test3 = { a, b ->
a + b
}
task(myGroovyTestFun).doLast {
println “start execute myGroovyTestFun”
test1(100, “Lucas”)
test2.call(100, 200)
println test3(100,200)
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
上面定义了三个闭包,每个闭包的调用方法都是call()方法,闭包的传参可通过call方法传入。在Terminal中输入命令:./gradlew myGroovyTestFun,得到结果:
Task :myGroovyTestFun
start execute myGroovyTestFun
a=100, b=Lucas, I am a closure!
a=100, b=200, I am a closure!
300
另外,如果闭包不指定参数,那么它会有一个隐含的参数
// 这里省略了闭包的参数类型
def a = [5,’hello’,’world’,false]
def b ={
println(it)
}
a.each(b)
简单用法介绍如上,如果遇到问题可先查询Groovy的文档:
http://www.groovy-lang.org/api.html
http://docs.groovy-lang.org/latest/html/groovy-jdk/index-all.html
2.2.3 List和Map
Groovy中的List、Map、Set等集合可视为java中集合类的加强版。
List操作和java几乎一致,注意的是groovy中List添加新元素可用左移位操作符<<:
def emptyList = []
def test = [1, ‘hello’,’world’, true]
test << 200
test[1] = 2
println test[0]
List操作符<<,左移位表示向List中添加新元素,这一点从文档当也能查到。
其实Map也有左移操作,这如果不查文档,将会非常费解
Map的使用类似:
def emptyMap = [:]
def user = [“age”:18, “name”:”Lucas”]
test[“age”] = 28
test.age= 38
对集合类,如果我们传递给闭包的是一个参数,闭包就把每一项作为参数;如果我们传递闭包2个参数,闭包把key和value作为参数:
def emptyMap = [:]
def test = [“age”:18, “name”:”Lucas”]
test.each { key, value ->
println “two parameters, find [${key} : ${value}]”
}
test.each {
println “one parameters, find [${it.key} : ${it.value}]”
}
2.2.4 List和Map
在Groovy中,文件访问要比Java简单的多,不管是普通文件还是xml文件。
根据File的eachLine方法,我们可以写出如下遍历代码,可以看到,eachLine方法也是支持1个或2个参数的,
def file = new File(“test.txt”)
println “read file using two parameters”
file.eachLine { line, lineNo ->
println “${lineNo} ${line}”
}
println “read file using one parameters”
file.eachLine { line ->
println “${line}”
}
outputs:
read file using two parameters
1 第一行
2 第二行
3 第三行
read file using one parameters
第一行
第二行
第三行
Groovy访问xml文件,也是比Java中简单多了。
Groovy访问xml有两个类:XmlParser和XmlSlurper,二者几乎一样,在性能上有细微的差别。
假设我们有一个xml,attrs.xml,如下所示:
<resources>
<declare-styleable name=”CircleView”>
<attr name=”circle_color” format=”color”>#98ff02</attr>
<attr name=”circle_size” format=”integer”>100</attr>
<attr name=”circle_title” format=”string”>renyugang</attr>
</declare-styleable>
</resources>
那么如何遍历它呢?
def xml = new XmlParser().parse(new File(“attrs.xml”))
// 访问declare-styleable节点的name属性
println xml[‘declare-styleable’].@name[0]
// 访问declare-styleable的第三个子节点的内容
println xml[‘declare-styleable’].attr[2].text()
outputs:
CircleView
renyugang
三 Groovy中的类
Groovy中的很多语法和Kotlin非常类似,如果熟悉Kotlin,学习Groovy将会非常容易上手。
Groovy中,所有的Class类型都可以省略.class:
func(File.class)
func(File)
def func(Class clazz) {
}
类似Kotlin,属性的Getter/Setter方法是默认实现的,无需再写Getter/Setter方法:
class Book {
String name
}
with 函数也类似Kotlin,会在with大括号的内部提供对象的上下文,我们可以直接使用with前面Book类的属性和方法:
Book bk = new Book()
bk.with {
id = 1
name = “android art”
}
同Kotlin,Groovy中的==是java中的equals,java中的==可以用Groovy中的.is()方法:
Groovy非空判断也比java简单很多,同样可参考kotlin,用?.来代替if(bean!=null)的非空判断:
println book?.buyer?.name
1.
在Groovy中,判断是否为真可以更简洁:
if (name != null && name.length > 0) {}
可以替换为:
if (name) {}
三元表达式:
def result = name != null ? name : “Unknown”
// 省略了name
def result = name ?: “Unknown”
1.
2.
3.
4.
在Groovy中switch方法可支持更多的参数类型:
switch (someone) {
case “hello world”: result = “is hello world”
break
case [4, 5, 6, ‘inList’]: result = “is list”
break
case 12..30: result = “is range”
break
case Integer: result = “is integer”
break
case Number: result = “is number”
break
case { it > 3 }: result = “number > 3”
break
default: result = “default”
}
参考文章:
Groovy官网
Gradle从入门到实战 – Groovy基础
Groovy 语言快速入门 – 简书
Groovy 概述_w3cschool