一、Gradle是目前Android主流的构建工具、我们在做项目的时候、有很多的配置都会放在项目的build.gradle文件中进行。
如版本、信息、包名、一些第三方依赖、或者打包时用到的签名、混淆文件信息等。android开发离不开gradle。我们经常会不可避免的与gradle打交道。所以学习gradle是很有必要的事情。
Gradle 是一个配置脚本,它的背后是由Groovy Language、 Gradle DSL、 Android DSL几门语言。其中dsl是指领域特定语言。只能用于特定的某个流域。今天我们先来学习Groovy。
Groovy是一门jvm语言。它最终会编译成class文件在jvm上执行。所以它与java类似。甚至可以与java进行混写。groovy的优势在于它有大量自己的特性与语法。更加方便的让我们以更少的代码完成与java同样的功能。
二、配置环境
1、配置java环境变量 新建用户变量JAVA_HOME、这里注意不要加;与bin路径:正确为 D:\AndroidStudio\jre\ 错误为 D:\AndroidStudio\jre\bin或者D:\AndroidStudio\jre\bin;
将JAVA_HOME 用户变量设置到系统变量path中 %JAVA_HOME%
2、配置Gradle环境变量 新建用户变量GRADLE_HOME C:\Users\lihaiyang.gradle\wrapper\dists\gradle-5.4.1-all\3221gyojl5jsh0helicew7rwx\gradle-5.4.1
将GRADLE_HOME用户变量加到系统变量path中 C:\Users\lihaiyang.gradle\wrapper\dists\gradle-5.4.1-all\3221gyojl5jsh0helicew7rwx\gradle-5.4.1\bin 系统变量是bin目录下 因为 此目录下有gradle.bat 文件
3、验证是否配置成功
打开控制台 cmd 执行 gradle命令 如图下所示为成功
二、groovy语言基础(与世界说句hello)
首先我们先来写一个学习任何语言的第一步先写个helloWorld出来
1、创建一个build.gradle 文件(注意。文件名改成xx.gradle是不行的) 书写以下代码,并执行gradle helloworld
解释一下。grdle 执行的是task 我们创建了一个helloworld的task 并打印一个println 输出hello world 函数
task(helloworld).doLast {
println "hello world"
}
恭喜各位。已经成功入门,进入groovy的世界了。
三、变量
对于groovy来说 它也是一种强类型的语言但是,它不用像java一样指定某个变量的类型,它会自己去推断。定义变量的方法 def xx;
task(helloworld).doLast {
def one = 1
def tow = "hello"
def three = 0.00d
def four = 0.1f
def five = true
println one.class
println tow.class
println three.class
println four.class
println five.class
}
在这里可以看出 最后打印出来的都是java.lang包下的数据类型。这里可以看出 它其实和java 是共通的。这里注意我们语句后面的;是可以省略的哦
四、定义方法
def func() {
}
int func(String str) {
retunr 1
}
int funcFour(){
1
}
def funcTow(def str) {
}
def funcThree(str) {
}
def funcFive(){
return 1; //这里的return 不可以省略
println "1" //这里没有打印 没有执行下去
println "2"
}
这里大家看到定义了几个方法、其中有很多是可以省略的 比如 返回值 return 语句 省略 return 、方法值参数可以省略类型、等。使用方法与java 一致 直接调用就可以了 。
五、String类型的拼接
对于String类型的拼接在我们AndroidManifest.xml文件中最为常见。我们先看一段代码
在图片上的代码中我们看到红框部分中标记的 applicationid 为我们的报名。我们可以在gradle中定义不同的报名来适配我们 androidManifest文件中使用。这样我们修改报名之后。只需要修改一个位置。不用到androidManifest文件中去全局替换了。以下为groovy书写。定义了a 与b变量 在c变量中使用%{x}进行引用。我们看我们打印出来的返回值,已经是拼接后的值了
def a = 1
def b = "hello"
def c = "a=${a}, b=${b}"
println c
outputs:
a=1, b=hello
六、闭包
groovy中有一个特殊的类型叫做闭包、作为一种数据类型存在。可以做为一个方法的参数与返回值。也可以作为一个变量而存在
{ parameters ->
code
}
def closure = { int a, String b ->
println "a=${a}, b=${b}, I am a closure!"
}
def test = { a, b ->
println "a=${a}, b=${b}, I am a closure!"
}
def ryg = { a, b ->
a + b
}
closure(100, "renyugang")
test.call(100, 200)
def c = ryg(100,200)
println c
a=100, b=renyugang, I am a closure!
a=100, b=200, I am a closure!
另外、如果闭包不指定参数、那么它有一个隐藏参数it
// 这里省略了闭包的参数类型
def test = {
println "find ${it}, I am a closure!"
}
test(100)
outputs:
find 100, I am a closure!
七、list 与map
如何定义list 与map
def emptyList = []
def emptyMap = [:]
以上相当于定义了两个空的object 集合 第一个为list 第二个为map
def test = [100, "hello", true]
def test = ["id":1, "name":"renyugang", "isMale":true]
对于list来讲 我们来看看怎么使用
def test = [100, "hello", true]
test[1] = "world" //将index 为1 的元素值替换为world
println test[0] //打印 index为0的元素
println test[1] //打印 index为1的元素
test << 200 // 添加一个值为200的元素
println test.size //打印list的大小
outputs:
100
world
4
以上代码为使用。其中有一个部分 为<< 位操作符。这个操作符与java中的add函数是一样的
http://www.groovy-lang.org/api.html groovy api文档
从文档中我们可以看到 其中我们看到有很多方法我们很熟悉,我们来使用以下
task(helloworld).doLast {
def text = [1,2,3,4,5]
println "textSize"+text.size()
text.add(6)
println "text中index为5"+text[5]
println "textSize"+text.size()
println "删除index为1的元素并打印其值"+text.remove(1)
println "获取index为0的元素"+text[0]
println "textSize"+text.size()
}
> Task :helloworld output
textSize5
text中index为56
textSize6
删除index为1的元素并打印其值2
获取index为0的元素1
textSize5
我们可以看到与我们java对应的方法没有差别。想要遍历怎么办。猜一下
task(helloworld).doLast {
def text = [1,2,3,4,5]
for (def entry : text){
println entry
}
}
> Task :helloworld output
1
2
3
4
5
map操作
task(helloworld).doLast {
def text = ["one": 1, "two": 2, "three": 3, "four": 4, "five": 5]
text << ["six" : 6] //增加元素
test["one"] = 2 //设置 key为one 的值为2
test.one= 900 //设置 key为one 的值为900
def keySet = text.keySet()
for (def key : keySet){
println "${key}+${text[key]}"
}
}
对于集合的遍历刚才我们已经通过与java 相同的方式进行了演示,如果我们想通过groovy的方式改怎么做的
我们可以查看另外一个文档http://docs.groovy-lang.org/latest/html/groovy-jdk/index-all.html
我们可以看到又一个each方法 他是使用闭包的方式进行遍历的
但是很不幸的是 list的each方法点进去是下面这样的
大爷的没有示例方法不知道怎么用啊,我们再看看map吧
这个还好有示例方法我们来依葫芦画瓢
def text = ["one": 1, "two": 2, "three": 3, "four": 4, "five": 5]
text.each { key, value ->
println "${key}=${value}"
}
text.each { entry ->
println entry
}
output
one=1
two=2
three=3
four=4
five=5
one=1
two=2
three=3
four=4
five=5
我们可以看到,成功了。这里我们发现他有两种使用方法,一种是 闭包是两个 变量 key value 它对应的就是
我们map 中的key value 第二种方式 就是是一个 entry 我们知道 在java 的map 中 每个元素是用entry 保存的所以这样也很符合java数据结构的设计,这里的entry 是可以省略的。上边已经说到 如果闭包中只有一个元素变量的话是可以省略的。大家可以试一下
好了map 搞定了。list咋办。猜吧(其实文档应该能找到)
def textTwo = [ 1, 2, 3, 4, 5]
textTwo.each{
println it
}
output
1
2
3
4
5
完美
八、io
groovy 相比于java io 方便很多。当然我们完全可以使用 groovy 支持的java的解析方式用来解析。这个就不演示了。大家可以试试。我们这次演示的是groovy 提供的闭包的方式进行。
1、文件读取
我们查看文档的话我们可以看到 支持file 读取的 有 eachByte eachLine 等
以上是api 文档中的一部分 但是还是没有示例代码。一万句mmp,幸亏有万能的翻译
可以看到参数 说是 第一个参数是行 第二个是可选参数 为从1开始的行号。来吧继续猜代码怎么写
我们再看看 这个方法是谁得
这么简单得翻译软件也可以剩下了 。 这个方法是 class File的方法 ,继续猜。java 咋拿File对象 这里咋拿
然后按照闭包的方式写
来吧 groovy 不是号称 自动推断类型么
def file = new def(text1.txt);
然后 mmp 报错,看来它还没成神
然后试了下
def file = new File("text1.txt");
不报错了
def file = new File("text1.txt");
file.eachLine{
println it
}
file.eachLine{ x,y ->
println "${x},${y}"
}
}
> Task :helloworld
1,这
2,里
3,一
4,次
5,成
6,功
xml解析,文档http://docs.groovy-lang.org/docs/latest/html/api/
这里只做演示。在文档中我也只查到了 java方式的方法。没有找到groovy方式的。大家可以自己在文档中找一找
<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 出了以上新特性以外还有其他的新特性
比如。默认的get set方法。groovy 中定义一个class 他的属性是默认存在get set方法的、或者所有的Class 类型参数 都可以省略.class
def func(Class class){
}
func(File.class)
func(File)
1、with操作符
Book bk = new Book()
bk.id = 1
bk.name = "android art"
bk.press = "china press"
可以简写为:
Book bk = new Book()
bk.with {
id = 1
name = "android art"
press = "china press"
}
2、判断是否为真
//java
if (name != null && name.length > 0) {}
可以替换为:
if (name) {}
3、简洁的三元表达式
def result = name != null ? name : "Unknown"
// 省略了name
def result = name ?: "Unknown"
4、简洁的非空判断
if (order != null) {
if (order.getCustomer() != null) {
if (order.getCustomer().getAddress() != null) {
System.out.println(order.getCustomer().getAddress());
}
}
}
可以简写为:
println order?.customer?.address
使用断言
在Groovy中,可以使用assert来设置断言,当断言的条件为false时,程序将会抛出异常,因为我们使用Groovy是用来写插件的。出错了直接抛。让使用插件的改 我们没必要捕获处理异常信息的。所以对异常处理不涉猎。
def check(String name) {
assert name
assert name?.size() > 3
}
1、对于switch 语句来讲。groovy 支持更丰富的条件语句
def x = "haha"
def result = ""
switch (x) {
case String:result = "string" //String
break
case "foo": //字符串
result = "found foo"
case "bar": //因为上边没有break 这里的判断允许失效。会执行下一个语句
result += "bar"
break
case [4, 5, 6, 'inList']: result = "list" //list
break
case { it > 3 }: result = "number > 3" //判断语句
break
case 12..30: result = "range" //范围
break
case Integer: result = "integer" //基本数据类型包装对象
break
case Number: result = "number" //基本数据类型包装对象的父类
break
default: result = "default"
}
println result