基于该网站深入理解groovy学习,Android Studio使用gradle工具进行打包编译的,而gradle使用groovy语言编写的,groovy是一种DSL语言,即Domain Specific Language领域相关语言,有很多默认的潜规则,使用起来非常灵活。
Groovy的开发环境
在ubuntu上搭建groovy的开发环境还是非常简单的,具体也可以参考官网groovy官网
- curl -s get.gvmtool.net | bash
- source "$HOME/.gvm/bin/gvm-init.sh"
- gvm install groovy
然后就可以创建一个*.groovy文件,比如说test.groovy文件,使用groovy *.groovy运行执行,感觉非常像shell脚本似的
Groovy的一些基础知识哦
- Groovy的注释标记和java是一样的
- Groovy语句可以不用分号结尾,也是减少了代码的输入量啊
- Groovy支持动态类型,和很多动态语言是一样的,定义变量的时候不用指定数据类型,但是尽量还是使用def关键字进行声明,虽然不用也是可以的,不过这个还是有坑。。。
def variable1 = 1 //可以不使用分号结尾
def varable2 = "I am a person"
def int x = 1 //变量定义时,也可以直接指定类型
4.定义函数的时候也是可以不用指定参数的类型的
String function(arg1,arg2){
...
}
函数的返回值也是可以不用指定的,没有指定函数返回值的会根据函数内最用一句的执行结果进行返回,并且使用def进行声明,举个栗子:
def fuction1(){
...
lastLine
}
String fuction2(){
return "the returned String"
}
5.Groovy对字符串的支持是非常强大的,不过还是有几个规则使用的方法
- 单引号中的内容是严格的字符串,不会对$中的变量进行转义,
- 双引号的字符串内容会对$表达式进行求值转义
- Groovy还是三个引号,如果是三个引号的话就可以任意的换行了
def singleQuote='I am $ dolloar' //输出就是I am $ dolloar
def doubleQuoteWithoutDollar = "I am one dollar" //输出 I am one dollar
def x = 1
def doubleQuoteWithDollar = "I am $x dolloar" //输出I am 1 dolloar
def multieLines = ''' begin
line 1
line 2
end '''
Groovy中的数据类型
在java的基本数据类型都已经被groovy包装成对象,只有对象啦。。。
Groovy容器类
- List链表,对应的Java中的List接口,一般是用ArrayList作为真正的实现类
- Map键值表,其底层对应的是Java中的LinkedHashMap
- Range,基于List实现的一种扩展
- List
变量定义:List变量由[]定义,比如
def aList = [5,'string',true] //List由[]定义,其元素可以是任何对象
变量存取:可以直接通过索引存取,而且不用担心索引越界。如果索引超过当前链表长度,List会自动
往该索引添加元素
assert aList[1] == 'string'
assert aList[5] == null //第6个元素为空
aList[100] = 100 //设置第101个元素的值为10
assert aList[100] == 100
那么,aList到现在为止有多少个元素呢?
println aList.size ===>结果是101
- Map
容器变量定义
变量定义:Map变量由[:]定义,比如
def aMap = ['key1':'value1','key2':true]
Map由[:]定义,注意其中的冒号。冒号左边是key,右边是Value。key必须是字符串,value可以是任何对象。另外,key可以用''或""包起来,也可以不用引号包起来。比如
def aNewMap = [key1:"value",key2:true] //其中的key1和key2默认被
处理成字符串"key1"和"key2"
不过Key要是不使用引号包起来的话,也会带来一定混淆,比如
def key1="wowo"
def aConfusedMap=[key1:"who am i?"]
aConfuseMap中的key1到底是"key1"还是变量key1的值“wowo”?显然,答案是字符串"key1"。如果要是"wowo"的话,则aConfusedMap的定义必须设置成:
def aConfusedMap=[(key1):"who am i?"]
Map中元素的存取更加方便,它支持多种方法:
println aMap.keyName <==这种表达方法好像key就是aMap的一个成员变量一样
println aMap['keyName'] <==这种表达方法更传统一点
aMap.anotherkey = "i am map" <==为map添加新元素
- Range类
def aRange = 1..5 <==Range类型的变量 由begin值+两个点+end值表示
左边这个aRange包含1,2,3,4,5这5个值
如果不想包含最后一个元素,则
def aRangeWithoutEnd = 1..<5 <==包含1,2,3,4这4个元素
println aRange.from
println aRange.to
Groovy的闭包
闭包是一个非常牛逼哄哄的东西,做iOS开发的应该不会默认,太方便了额,闭包,是一种数据类型,它代表了一段可执行的代码。在Groovy中定义格式是这样的
def xxx = {paramters -> code} //或者
def xxx = {无参数,纯code} //这种case不需要->符号
def aClosure = {
//闭包是一段代码,所以需要用花括号括起来..
String param1, int param2 -> //这个箭头很关键。箭头前面是参数定义,箭头后面是代码
println"this is code" //这是代码,最后一句是返回值,
//也可以使用return,和Groovy中普通函数一样
}
//调用
aClosure.call("this is string",100) //或者
aClosure("this is string", 100)
如果闭包没定义参数的话,则隐含有一个参数,这个参数名字叫it,和this的作用类似。it代表闭包的参数。
- each函数调用的圆括号不见了!原来,Groovy中,当函数的最后一个参数是闭包的话,可以省略圆括号。
def testClosure(int a1,String b1, Closure closure){
//do something
closure() //调用闭包
}
那么调用的时候,就可以免括号!
testClosure (4, "test", {
println "i am in closure"
} ) //红色的括号可以不写..
脚本类、文件I/O和XML操作
脚本中的变量和作用域
文件的I/O操作
groovy的I/O操作在原有Java的基础上进行了更为简便的封装
- 读文件
def targetFile = new File(文件名); //<==File对象还是要创建的。
//直接得到文件内容
targetFile.getBytes() //<==文件内容一次性读出,返回类型为byte[]
//使用InputStream.InputStream
def ism = targetFile.newInputStream()
//操作ism,最后记得关掉
ism.close
//使用闭包操作inputStream
targetFile.withInputStream{ ism ->
//操作ism.不用close。Groovy会自动替你close
}
//写文件和读文件一样
def srcFile = new File(源文件名)
def targetFile = new File(目标文件名)
targetFile.withOutputStream{ os->
srcFile.withInputStream{ ins->
os << ins //利用OutputStream的<<操作符重载,完成从inputstream到OutputStream
//的输出
}
}
//
XML操作
除了I/O异常简单之外,Groovy中的XML操作也极致得很。Groovy中,XML的解析提供了和XPath类似的方法,名为GPath。这是一个类,提供相应API。关于XPath,请看Wiki。
GPath功能包括:给个例子好了,来自Groovy官方文档
test.xml文件:
<response version-api="2.0">
<value>
<books>
<book available="20" id="1">
<title>Don Xijote</title>
<author id="1">Manuel De Cervantes</author>
</book>
<book available="14" id="2">
<title>Catcher in the Rye</title>
<author id="2">JD Salinger</author>
</book>
<book available="13" id="3">
<title>Alice in Wonderland</title>
<author id="3">Lewis Carroll</author>
</book>
<book available="5" id="4">
<title>Don Xijote</title>
<author id="4">Manuel De Cervantes</author>
</book>
</books>
</value>
</response>
groovy解析
//第一步,创建XmlSlurper类
def xparser = new XmlSlurper()
def targetFile = new File("test.xml")
//轰轰的GPath出场
GPathResult gpathResult =xparser.parse(targetFile)
//开始玩test.xml。现在我要访问id=4的book元素。
//下面这种搞法,gpathResult代表根元素response。通过e1.e2.e3这种
//格式就能访问到各级子元素....
def book4 = gpathResult.value.books.book[3]
//得到book4的author元素
def author = book4.author
//再来获取元素的属性和textvalue
assert author.text() == ' Manuel De Cervantes '
//获取属性更直观
author.@id == '4' //或者
author['@id'] == '4'
//属性一般是字符串,可通过toInteger转换成整数
author.@id.toInteger() == 4
//好了。GPath就说到这。再看个例子。我在使用Gradle的时候有个需求,就是获取AndroidManifest.xml版本号(versionName)。有了GPath,一行代码搞定,请看:
def androidManifest = newXmlSlurper().parse("AndroidManifest.xml")
println androidManifest['@android:versionName']
//或者
println androidManifest.@'android:versionName'
学习自InfoQ