课程导学

会Ant,会Maven,为什么还要学会Gradle

  • 一款最新的 ,功能最强大的构建 工具,用它逼格更高
  • 使用程序代替传统的XML配置,项目构建更灵活
  • 丰富的第三方插件,让你随心所欲使用
  • 完善Android,Java开发技术体系
  • 提升自动化构建技术深度
  • 进阶为高级工程师

1. Gradle相关介绍及开发环境搭建

领域特定语言DSL介绍

  • 全称domain specific language
  • 有哪些常见的DSL语言及特点.
    • SQL,CSS,HTML,Shell,JSON等等
    • DSL语言有别于其他通用语言如:C++,Java,C#,DSL常在特殊的场景或领域中使用
    • 通用语言大而全,DSL语言小而细

◆核心思想: 求专不求全 解决特定问题

groovy介绍

  • 是一种基于JVM的敏捷开发语言
  • 结合 了Python、Ruby和Smalltalk的许 多强大的特性
  • groovy可以 与Java完美结合,而且可以使用java所有的库
groovy特性
  • 语法上支持动态类型,闭包等新一代语言特性
  • 无缝集成所有已经存在的Java类库
  • 即支持面向对 象编程也支持面向过程编程
groovy优势
  • 一种更加敏捷的编程语言
  • 入门非常的容易, 但功能非常的强大
  • 即可以作为编程语宫也可以作为脚本语言
  • 熟练掌握Java的同学会非常容易掌握Groovy
Linux下环境的搭建
  1. 安装好JDK环境
  2. 到官网下载groovySDK,解压到合适的位置

image-20211014200005229

  1. 添加到环境变量

image-20211014195606030

image-20211014200205145

创建groovy工程

image-20211014200545669

永远的HelloWrold
  • 可以直接写Java代码

image-20211014201139254

  • 使用Groovy实现

image-20211014201408500

  • 编译之后还是会有类和main方法

image-20211014202446670

2. Gradle核心语法讲解及实战

groovy基础语法

groovy中的变量

  • 变量的类型

    • 基本类型(定义为基本类型会自动转为对应的包装类型)
    • 对象类型
  • 变量的定义

    • 强类型定义方式 (声明变量时直接指定类型)
    • 弱类型def定义方式(编译器自动推断类型)
  • 变量只是自己使用不会使用于其他类或者模块推荐def

  • 变量会被其他类使用推荐定义为强类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package variable

int x = 10

println x.class

double y = 3.14
println y.class

def x_1 = 11
println x_1.class
def y_1 = 3.1415
println y_1.class
def name = 'Qndroid'
println name.class

x_1 = 'Test'
println x_1.class

image-20211014205815445

groovy中字符串

字符串

  • String
  • GString
    • 常用的三种定义方式
    • 新增操作符
    • 新增API讲解

默认 单引号、双引号、还是三引号创建的都为 java.lang.String 类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package variable


def name = 'a single \'a\'string'

println name
println name.class

def thupleName = '''\
line one
line two
line three
'''
println thupleName
def doubleName = "this a common String"
println doubleName.class

name = "Qndroid"
println name.class
def sayHello = "Hello: ${name}"
println sayHello Hello: Qndroid
println sayHello.class //class org.codehaus.groovy.runtime.GStringImpl

image-20211014222331351

1
2
3
4
5
6
7
8
def sum = "the sum of 2 and 3 equals ${2 + 3}" //可扩展做任意的表达式
println sum // the sum of 2 and 3 equals 5
def result = echo(sum)
println result.class // class java.lang.String

String echo(String message) {
return message
}

字符串方法详解

String方法

  • java.lang.String

  • DefaultGroovyMethods

  • stringGroovyMethods

    • 普通类型的参数
    • 闭包类型的参数
  • 字符串填充

1
2
3
4
5
6
7
8
9
10
def str = "groovy"

//字符串为中心开始填充
println str.center(9,"c") //cgroovycc

//从已有字符串左边开始填充
println str.padLeft(9, 'a') //aaagroovy

//从已有字符串右边开始填充
println str.padRight(9, 'b') //groovybbb
  • 字符串比较
1
2
3
4
5
6
7
def str = "groovy Hello"
def str2 = 'Hello'
println str > str2 // true
println str[0] // g
println str[0..4] // groov
println str - str2 // groovy
println str.minus(str2) // groovy 和上面减法一样
  • 字符串常用方法
1
2
3
4
5
6
7
8
9
10
def str = "groovy Hello"

// 倒序输出
println str.reverse() // olleH yvoorg

// 首字母大写
println str.capitalize() // Groovy Hello

//是否为数字类型字符串
println str.isNumber() //false

逻辑控制

  • 顺序逻辑

    • 单步往下执行
  • 条件逻辑

    • if/else
    • switch/case
  • 循环逻辑

    • for循环
    • while循环
  • switch/case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package variable

def x = 1.23
def result
switch (x) {
case 'foo':
result = 'found foo'
break
case 'bar':
result = 'bar'
break
case [ 4, 5, 6, 'inlist']: //列表
result = 'list'
break
case 12..30:
result = 'range' //范围
break
case Integer:
result = 'integer'
break
case BigDecimal:
result = 'big decimal'
break
default: result = 'default'
}

//输出结果: big decimal
  • 循环逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//对范围的for循环
def sum = 0
for (i in 0..9) {
sum += i
}
//println sum
sum = 0


/**
* 对List的循环
*/

for (i in [1, 2, 3, 4, 5, 6, 7, 8, 9]) {
sum += i
}

/**
* 对Map进行循环
*/
for (i in ['lili': 1, 'luck': 2, 'xiaoming': 3]) {
sum += i.value
}

groovy闭包讲解

groovy中闭包基础详解

  • 无参数闭包
1
2
3
4
5
6
7
8
package variable

def clouser= {println("Hello Groovy")}

clouser.call() //调用闭包
clouser() //调用闭包

// 执行后输出两次 Hello Groovy
  • 带参数闭包
1
2
3
4
def clouser= { String name -> println("Hello ${name}")}
def name = "zzxx"
clouser(name)
// 执行后输出 Hello zzxx
  • 多个参数
1
2
3
4
5
6
7
8
package variable

def clouser= { String name , int age ->
println("Hello ${name} my age is $age" )
}

def name = "zzxx"
clouser(name,12)
  • 默认参数it
1
2
3
4
5
6
7
8
package variable

def clouser= {
println("Hello ${it} " )
}

def name = "zzxx"
clouser(name)
  • 闭包返回值

groovy 中闭包一定有返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package variable

def clouser = {
return "Hello ${it} "
}
def name = "zzxx"
def result = clouser(name)
println(result)

clouser = {
println("Hello ${it} ")
}
result = clouser(name)
println(result)

image-20211015105053913

groovy中闭包使用详解

与基本类型的结合使用
  • 求一个数的阶乘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package variable


int fab(int number) {
int result = 1
1.upto(number, { num -> result *= num })
return result
}

int fab2(int number) {
int result = 1
// groovy 中闭包可以不放到括号中 直接写道括号外面
number.downto(1) { num -> result *= num }
return result
}

println fab(5) //120
println fab2(5) //120
  • 累加求和
1
2
3
4
5
6
7
int cal(int number) {
int result = 0
number.times { num -> result += num }
return result
}

println cal(101)
与String结合使用
  • each 遍历
1
2
3
4
def str = "Hello Groovy"

str.each { String temp -> print temp.multiply(2) } //每一项乘2 HHeelllloo GGrroooovvyy
println str.each { String temp -> temp } // 返回值为本身
  • find 来查找符合条件的第一个
1
println str.find{String s -> s.isNumber()}
  • findAll 来查找符合条件的全部
1
2
def list = str.findAll({ s -> s.isNumber()})
println list.toListString()
  • 任意一个元素满足条件返回true
1
println str.any {s -> s.isNumber()}
  • 所有元素满足条件返回true
1
println str.every {s -> s.isNumber()}
  • Collect
1
2
list = str.collect {s->s.toUpperCase()}
printl list

groovy中闭包进阶讲解

  • 这方面最能体现groovy中闭包比JS的闭包,Java的lambda强大的地方
闭包关键变量
1
2
3
4
5
6
7
8
9
10
/**
* 闭包的三个重要变量:this,owner,delegate
*/
def scriptClouser = {
println "scriptClouser this: " + this //代表闭包定义处的类
//闭包定义在类中和 this 一样但是闭包可以定义在闭包中嵌套闭包就表示对象
println "scriptClouser owner: " + owner //代表闭包定义处的类或者对象
println "scriptClouser delegate: " + delegate //代表任意对象默认与owner一致
}
scriptClouser.call()

image-20211015220149281

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Person {
//定义了一个内部类class Person i
def static classClouser = {
println "classClouser this: " + this
println "classClouser owner: " + owner
println "classClouser delegate: " + delegate
}

def static say() {
def classClouser = {
println "methodClassClouser this:" + this
println "methodClassClouser owner: " + owner
println "methodClassClouser delegate: " + delegate
}
classClouser.call()
}
}

Person.classClouser.call()
Person.say()

image-20211015221525195

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Person {
//定义了一个内部类class Person i
def classClouser = {
println "classClouser this: " + this
println "classClouser owner: " + owner
println "classClouser delegate: " + delegate
}

def say() {
def classClouser = {
println "methodClassClouser this:" + this
println "methodClassClouser owner: " + owner
println "methodClassClouser delegate: " + delegate
}
classClouser.call()
}
}

Person person = new Person();
person.classClouser.call()
person.say()

image-20211015221634201

1
2
3
4
5
6
7
8
9
def nestClouser = {
def innerClouser = {
println "innerClouse this: " + this
println "innerclouser owner: " + owner
println "innerClouser delegate: " + delegate
}
innerClouser.call()
}
nestClouser.call()

image-20211015222955687

  • 人为修改delegate(this和 owner是不可以修改的)

image-20211015223145440

闭包委托策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Student {
String name
def pretty = { "My name is ${name}" }

String toString() {
pretty.call()
}
}

class Teacher {
String name
}

def stu = new Student(name: 'Sarash')
def tea = new Teacher(name: 'Qndroid')
println stu.toString()

//这样毫无疑问 输出 是 My name is Sarash

现在想让输出 toString 打印 出 name 为 Qndroid

  • 委托策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Student {
String name
def pretty = { "My name is ${name}" }

String toString() {
pretty.call()
}
}

class Teacher {
String name
}

def stu = new Student(name: 'Sarash')
def tea = new Teacher(name: 'Qndroid')

stu.pretty.delegate = tea
// 设置 默认委托策略 为 DELEGATE 默认为 OWNER_FIRST
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST
println stu.toString()

image-20211015224250706

  • DELEFATE_FIRST中字段不存在时

image-20211015230423598

  • DELEFATE_ONLY中字段不存在时

image-20211015230522848

与数据结构结合使用

与文件等结合使用

groovy数据结构

groovy中列表详解

列表的定义
1
2
3
4
5
6
7
//def list = new ArrayList() //java的定义方式
def list = [1, 2, 3, 4, 5]
println list.class // java.util.ArrayList
println list.size()class // 5

def array = [1, 2, 3, 4, 5] as int[] //定义一个数组
int[] array2 = [1, 2, 3, 4, 5] // 直接使用强类型定义一个数组
列表添加元素
1
2
3
4
5
6
7
8
9
10
11
/**
* list的添加元素
*/
def list = [1, 2, 3, 4, 5]
list.add(6)
list.leftShift(7)
list << 8
println list.toListString() // [1, 2, 3, 4, 5, 6, 7, 8]
def plusList = list + 9
println plusList.toListString() // [1, 2, 3, 4, 5, 6, 7, 8, 9]

列表删除元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def list = [1, 2, 3, 4, 5]
list.add(6)
list.leftShift(7)
list << 8
list << 9
list << 10

/**
* list的删除操作
*/
list.remove(7)
println list.toListString() //[1, 2, 3, 4, 5, 6, 7, 9, 10]
list.remove((Object) 7)
println list.toListString() //[1, 2, 3, 4, 5, 6, 9, 10]

list.removeAt(7) //和 list.remove(7) 一样
println list.toListString() //[1, 2, 3, 4, 5, 6, 9]
list.removeElement(6) //和 list.remove((Object) 6) 一样
println list.toListString() //[1, 2, 3, 4, 5, 9]
list.removeAll { return it % 2 == 0 }
println list.toListString() //[1, 3, 5, 9]
println list - [6, 7] //[1, 3, 5]
println list.toListString() //[1, 3, 5, 9]
列表排序
  • 自然排序(J和Java中一样)
1
2
def sortList = [6, -3, 9, 2, -7, 1, 5]
Collections.sort(sortList)
  • 自定义排序规则(绝对值从小到大)
1
2
3
4
5
Comparator mc = { a, b ->
a == b ? 0 :
Math.abs(a) < Math.abs(b) ? -1 : 1
}
Collections.sort(sortList, mc)
  • 自定义排序规则(绝对值从大到小)
1
2
3
4
5
sortList.sort { a, b ->
a == b ? 0 :
Math.abs(a) < Math.abs(b) ? 1 : -1
}
println sortList
  • 非number类型排序(按照字符串长度)
1
2
3
def sortStringList = ['abc', 'z', 'Hello', 'groovy', 'java']
sortStringList.sort { it -> return it.size() }
println sortStringList
列表查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def findList = [-3, 9, 6, 2, -7, 1, 5]

//第一个对二求余等于0
println findList.find { return it % 2 == 0 }
//所有对二求余不等于0
println findList.findAll { return it % 2 != 0 }
//是否存在对二求余不等于0
println findList.any { return it % 2 != 0 }
// 是否全部对二求余等于0
println findList.every { it % 2 == 0 }

// 指定规则最小值
println findList.min { return Math.abs(it) }
// 指定规则最大值
println findList.max { return Math.abs(it) }
// 对二求余数目
println findList.count { return it % 2 == 0 }

groovy中的映射详解

定义,访问,添加元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package datastruct

//def map = new HashMap() // Java中定义方式
def colors = [red : 'ff0000',
green: '00ff00',
blue : '0000ff']


//索引方式
println colors.getAt('red') //Java中访问方式
println colors['red'] // ff0000
println colors.red // ff0000

//添加元素
colors.yellow = 'ffff00'
colors.complex = [a: 1, b: 2] // 添加一个Map
println colors.getClass() //class java.util.LinkedHashMap
遍历元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//遍历Entry
students.each { def student ->
println "the key is ${student.key}, " +
" the value is ${student.value}"
}
//带索引的遍历
students.eachWithIndex { student, index ->
println "index is ${index},the key is ${student.key}, " +
" the value is ${student.value}"
}

//直接遍历key-value
students.each { key, value ->
println "the key is ${key}, " +
" the value is ${value}"
}
//带索引直接遍历key-value
students.eachWithIndex { key, value, index ->
println "the index is ${index},the key is ${key}, " +
" the value is ${value}"
}

image-20211016111947339

Map的查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def students = [
1: [number: '0001', name: 'Bob',
score : 55, sex: 'male'],
2: [number: '0002', name: 'Johnny',
score : 62, sex: 'female'],
3: [number: '0003', name: 'Claire',
score : 73, sex: 'female'],
4: [number: '0004', name: 'Amy',
score : 66, sex: 'male']
]

def entry = students.find { def student ->
return student.value.score >= 60
}
println entry //2={number=0002, name=Johnny, score=62, sex=female}

def entrys = students.findAll { def student ->
return student.value.score >= 60
}
println entrys //[2:[number:0002, name:Johnny, score:62, sex:female], 3:[number:0003, name:Claire, score:73, sex:female], 4:[number:0004, name:Amy, score:66, sex:male]]


def count = students.count { student ->
student.value.score >= 60 && student.value.sex == 'male'
}
println count // 1
Collect收集
1
2
3
4
5
6
7
8
def names = students.findAll { def student ->
return student.value.score >= 60
}.collect {
return it.value.name
}
println names.toListString()

//[Johnny, Claire, Amy]
group分组
1
2
3
4
5
6
7
def group = students.groupBy { def student ->
return student.value.score >= 60 ? '及格' : '不及格'
}
println group.toMapString()


//[不及格:[1:[number:0001, name:Bob, score:55, sex:male]], 及格:[2:[number:0002, name:Johnny, score:62, sex:female], 3:[number:0003, name:Claire, score:73, sex:female], 4:[number:0004, name:Amy, score:66, sex:male]]]
排序
1
2
3
4
5
6
7
8
def sort = students.sort { def student1, def student2 ->
Number score1 = student1.value.score
Number score2 = student2.value.score
return score1 == score2 ? 0 : score1 < score2 ? -1 : 1
}
println sort.toMapString()

[1:[number:0001, name:Bob, score:55, sex:male], 2:[number:0002, name:Johnny, score:62, sex:female], 4:[number:0004, name:Amy, score:66, sex:male], 3:[number:0003, name:Claire, score:73, sex:female]]

groovy中的范围详解

定义
1
2
3
4
5
6
7
8
package datastruct

def range = 1..10
println range[0] //1
println range.contains(10) //true
println range.from //1
println range.to //10

遍历
1
2
3
4
5
6
7
8
//遍历
range.each {
println it
}

for (i in range) {
println i
}
  • 范围用在switch中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def result = getGrade(75)
println result

def getGrade(Number number) {
def result
switch (number) {
case 0..<60:
result = '不及格'
break
case 60..<70:
result = '及格'
break
case 70..<80:
result = '良好'
break
case 80..100:
result = '优秀'
break
}

return result
}

groovy面向对象

groovy中类,接口等的定义和使用

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 1.groovy中默认都是public
*/
class Person implements Serializable {

String name

Integer age

def increaseAge(Integer years) {
this.age += years
}
}
  • 访问类中属性和方法
1
2
3
4
5
6
7
8
package objectorention

def person = new Person(name: 'Qndroid', age: 26)
println person.age //26
println person.name //Qndroid
//
println "the name is ${person.getName()},the age is ${person.getAge()}" //the name is Qndroid,the age is 26
println person.increaseAge(10) //36
Groovy中接口
1
2
3
4
5
6
7
8
9
/**
* 接口中不许定义非public的方法
*/
interface Action {

void eat()
void drink()
void play()
}
  • Peroson实现该接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Person implements Action {

String name

Integer age

def increaseAge(Integer years) {
this.age += years
}

@Override
void eat() {

}

@Override
void drink() {

}

@Override
void play() {

}
}
  • 需要为方法提供默认的实现 使用trait
1
2
3
4
5
6
7
8
9
trait DefualtAction {

abstract void eat()

void play() {
println ' i can play.'
}

}
  • Person实现 DefualtAction 只需要重写eat方法即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Person implements DefualtAction {

String name

Integer age

def increaseAge(Integer years) {
this.age += years
}

@Override
void eat() {

}

groovy中的元编程

什么是元编程,简单理解 即编写代码执行的时期,有解释执行的js,编译执行的Java,运行时期执行的代码,譬如Java中的反射。

本小节主要是groovy中 运行时期执行的代码 专业术语 runtime

groovy运行期的能力图

  • Java中调用方法没有该方法会直接编译不通过
  • Groovy中没有该方法 类也是可以通过编译的

image-20211016140235561

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package objectorention

/**
* 1.groovy中默认都是public
*/
class Person implements Serializable {

String name

Integer age

def increaseAge(Integer years) {
this.age += years
}

/**
* 一个方法找不到时,调用它代替
* @param name
* @param args
* @return
*/
def invokeMethod(String name, Object args) {
return "the method is ${name}, the params is ${args}"
}

def methodMissing(String name, Object args) {

return "the method ${name} is missing"
}
}

1
2
3
4
package objectorention

def person = new Person(name: 'Qndroid', age: 26)
println person.cry()

image-20211016143018592

为类动态的添加一个属性
1
2
3
4
5
6
//为类动态的添加一个属性
Person.metaClass.sex = 'male'
def person = new Person(name: 'Qndroid', age: 26)
println person.sex //male
person.sex = 'female'
println "the new sex is:" + person.sex //the new sex is:female
为类动态的添加方法
1
2
3
4
5
6
Person.metaClass.sex = 'male'

//为类动态的添加方法
Person.metaClass.sexUpperCase = { -> sex.toUpperCase() }
def person2 = new Person(name: 'Qndroid', age: 26)
println person2.sexUpperCase() //MALE
为类动态的添加静态方法
1
2
3
4
5
Person.metaClass.static.createPerson = {
String name, int age -> new Person(name: name, age: age)
}
def person3 = Person.createPerson('zzxx', 26)
println person3.name + " and " + person3.age //zzxx and 26
  • 外部注入的方法 全局可用
1
ExpandoMetaClass.enableGlobally()

必知必会

  • 对groovy整体语法特点有一个了解
  • 掌握groovy的变量,字符串,数据结构的用法
  • 掌握groovy的闭包和面向对象思想

3. Groovy高级用法实战

3.1 JSON操作详解

转JSON字符串

1
2
3
4
5
6
7
8
9
10
11
12
package file

import groovy.json.JsonOutput
import objectorention.Person

def list = [new Person(name: 'John', age: 25),
new Person(name: 'Major ', age: 26)]
//list转JSON
def json = JsonOutput.toJson(list)
println json
//JSON格式化输出
println JsonOutput.prettyPrint(json)

image-20211016150336137

解析JSON字符串

1
2
3
4
5
6
7
8
9
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import objectorention.Person

def list = [new Person(name: 'John', age: 25),
new Person(name: 'Major ', age: 26)]
def json = JsonOutput.toJson(list)
def jsonSlurper = new JsonSlurper();
println jsonSlurper.parse(json.getBytes()) //[[age:25, name:John], [age:26, name:Major ]]
  • 获取网络请求返回JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def reponse = getNetworkData('http://yuexibo.top/yxbApp/course_detail.json')

println reponse.data.head.name

def getNetworkData(String url) {
//发送http请求
def connection = new URL(url).openConnection()
connection.setRequestMethod('GET')
connection.connect()
def response = connection.content.text
//将json转化为实体对象
def jsonSluper = new JsonSlurper()
return jsonSluper.parseText(response)
}

3.2 XML操作详解

如何解析一个xml格式数据

  • 定义需要解析的xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
final String xml = '''
<response version-api="2.0">
<value>
<books id="1" classification="android">
<book available="20" id="1">
<title>疯狂Android讲义</title>
<author id="1">李刚</author>
</book>
<book available="14" id="2">
<title>第一行代码</title>
<author id="2">郭林</author>
</book>
<book available="13" id="3">
<title>Android开发艺术探索</title>
<author id="3">任玉刚</author>
</book>
<book available="5" id="4">
<title>Android源码设计模式</title>
<author id="4">何红辉</author>
</book>
</books>
<books id="2" classification="web">
<book available="10" id="1">
<title>Vue从入门到精通</title>
<author id="4">李刚</author>
</book>
</books>
</value>
</response>
'''
  • 解析XML
1
2
3
4
5
6
7
//开始解析此xml数据
def xmlSluper = new XmlSlurper()
def response = xmlSluper.parseText(xml)

println response.value.books[0].book[0].title.text() //疯狂Android讲义
println response.value.books[0].book[0].author.text() //李刚
println response.value.books[1].book[0].@available //10
  • 遍历XML元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def xmlSluper = new XmlSlurper()
def response = xmlSluper.parseText(xml)
def list = []
response.value.books.each { books ->
//下面开始对书结点进行遍历
books.book.each { book ->
def author = book.author.text()
if (author.equals('李刚')) {
list.add(book.title.text())
}
}
}
println list.toListString()

//深度遍历xml数据
def titles = response.depthFirst().findAll { book ->
return book.author.text()
}
println titles.toListString()

//广度遍历xml数据

def name = response.value.books.children().findAll { node ->
node.name() == 'book' && node.@id == '2'
}.collect { node ->
return node.title.text()
}

println name

如何创建一个xml格式数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
* 生成xml格式数据
* <langs type='current' count='3' mainstream='true'>
<language flavor='static' version='1.5'>Java</language>
<language flavor='dynamic' version='1.6.0'>Groovy</language>
<language flavor='dynamic' version='1.9'>JavaScript</language>
</langs>
*/
def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw) //用来生成xml数据的核心类
//根结点langs创建成功
xmlBuilder.langs(type: 'current', count: '3',
mainstream: 'true') {
//第一个language结点
language(flavor: 'static', version: '1.5') {
age('16')
}
language(flavor: 'dynamic', version: '1.6') {
age('10')
}
language(flavor: 'dynamic', version: '1.9', 'JavaScript')
}

println sw

def langs = new Langs()
xmlBuilder.langs(type: langs.type, count: langs.count,
mainstream: langs.mainstream) {
//遍历所有的子结点
langs.languages.each { lang ->
language(flavor: lang.flavor,
version: lang.version, lang.value)
}
}
//对应xml中的langs结点
class Langs {
String type = 'current'
int count = 3
boolean mainstream = true
def languages = [
new Language(flavor: 'static',
version: '1.5', value: 'Java'),
new Language(flavor: 'dynamic',
version: '1.3', value: 'Groovy'),
new Language(flavor: 'dynamic',
version: '1.6', value: 'JavaScript')
]
}
//对应xml中的languang结点
class Language {
String flavor
String version
String value
}

3.3 文件操作

  • java文件处理

    • 节点流,InputStream, OutputStream及其子类
    • 处理流,Reader,Writer及其子类
  • 读取文件

1
2
3
4
5
6
7
8
9
def file = new File('../../a.txt')

file.eachLine { line -> println line}

def text = file.getText()
println text
// 一行一行读取存放到List中
def result = file.readLines()
println result

image-20211016183948495

  • 读取文件部分内容
1
2
3
4
5
6
def reader = file.withReader { reader ->
char[] buffer = new char[10]
reader.read(buffer)
return buffer
}
println reader //输出 Hello Kotl
  • 复制文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def result = copy('../../a.txt', '../../b.txt')
println result

def copy(String sourcePath, String destationPath) {
try {
//首先创建目标文件
def desFile = new File(destationPath)
if (!desFile.exists()) {
desFile.createNewFile()
}

//开始copy
new File(sourcePath).withReader { reader ->
def lines = reader.readLines()
desFile.withWriter { writer ->
lines.each { line ->
writer.append(line + "\r\n")
}
}
}
return true
} catch (Exception e) {
e.printStackTrace()
}
return false
}
  • 序列化对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package objectorention

/**
* 1.groovy中默认都是public
*/
class Person implements Serializable {

String name

Integer age

def increaseAge(Integer years) {
this.age += years
}

/**
* 一个方法找不到时,调用它代替
* @param name
* @param args
* @return
*/
def invokeMethod(String name, Object args) {

return "the method is ${name}, the params is ${args}"
}


def methodMissing(String name, Object args) {

return "the method ${name} is missing"
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def person = new Person(name: 'Qndroid', age: 26)
saveObject(person, '../../person.bin')

def result = (Person) readObject('../../person.bin')
println "the name is ${result.name} and the age is ${result.age}"

def saveObject(Object object, String path) {
try {
//首先创建目标文件
def desFile = new File(path)
if (!desFile.exists()) {
desFile.createNewFile()
}
desFile.withObjectOutputStream { out ->
out.writeObject(object)
}
return true
} catch (Exception e) {
}
return false
}

def readObject(String path) {
def obj = null
try {
def file = new File(path)
if (file == null || !file.exists()) return null
//从文件中读取对象
file.withObjectInputStream { input ->
obj = input.readObject()
}
} catch (Exception e) {

}
return obj
}

groovy与java对比

  • 写法上:没有java那么多的限制
  • 功能上:对java已有的功能进行了极大的扩展
  • 作用上:即可以编写应用,也可以编写脚本

4. Gradle生命周期探索

4.1 gradle基本概念

  • 如果把gradle仅仅看作一个构建工具,那么Gradle的功能就被大大局限了,Gradle更可以被看作编程框架
  • Gradle有自己的语法(Groovy)又有自己的Api,所以可以被看作编程框架
  • 通过编程实现构建需求是Gradle最大的特色,也是Gradle的核心

gradle组成

  • groovy核心语法

  • build script block

  • gradle api

  • 灵活性上

  • 粒度性上

  • 扩展性上

  • 兼容性上

image-20211016194151777

image-20211016200737216

Gradle核心之Project详解及实战

深入了解Project

Project核心API讲解

Project核心API实战