Groovy 概述
DSL 领域特定语言
Groovy是脚本的DSL
Groovy基于JVM的开发语言
Groovy可以与Java完美结合,而且可以使用java所有类库
Groovy特性
语法上支持动态类型,闭包等新一代语言特性
Groovy优势
- 更加敏捷
- 既可以作为编程语言,也可以作为脚本语言
第一个Groovy程序
println ‘Hello Groovy’
Groovy 语法详解
基础语法
groovy中变量
- 变量的类型
- 基本类型 实际上也是对象类型(基本类型会自动转换为包装类型)
1
2
3double y = 3.14 println y.class //class java.lang.Double
- 对象类型
- 变量的定义
- 强类型定义方式
- 弱类型def定义方式 编译器会根据后边的赋值自动分配默认类型(小数会被认为是BigDecimal)
1
2
3def b = 3.14 println b.class //class java.math.BigDecimal
当变量只有自己使用可定义def,当在公共代码块中定义时,使用强类型
groovy中字符串中的详解
java :String
groovy : GString
常用的定义方式:
- def name = 'a single name ’ a ‘’ 是转义符 类型:String
- def tribleName = ‘’‘带格式的字符串 ‘’’ 类型:String
- def doubleName = “可扩展字符串” 类型:String
1
2
3
4
5
6def a = "Groovy" def sayHello = "Hello $a" println(sayHello) //此时sayHello的类型是GString def sum = "The sum of 2 and 3 equals ${2 + 3}"
可扩展任意的表达式
不必纠结是String还是GString,GString可以直接转换为String(Groovy的内部实现)
新增操作符:
- java.lang.String
- DefaultGroovyMethods(Groovy为所有类型新增的方法)
- StringGroovyMethods(继承于上,并做了相应的扩展)其中参数的类型有:1,普通类型的参数;2,闭包类型的参数
方法及操作符
- center(int i,String a);用a在字符串中进行填充,直到字符串的长度为i;
- center(int i);用空格进行填充
- padLeft(int i,String a);用a在字符串的左边进行填充,直到字符串长度为i;
- str1 > str2 字符串的比较,比较的各位置字符在表中的编号;返回boolean类型
- str[i] 返回第i位的字符
- str[i…j]返回从i位到j位之间字符组成的字符串
- minus(String s);若s是字符串中的一部分,则删掉后返回,相同的办法 str1-str2
- reserve();字符串反转
- capitalize()首字母大写
- isNumber()判断是否是数字
- toInteger()转换为Integer
逻辑控制
在Groovy中Swith…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
26def 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 = 'bigdecimal' break default: result = 'default' } println result;//bigdecimal
for循环的几种变体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//对范围的循环 def sum = 0 for(i in 0..9) { sum += i } //对list的循环 sum = 0; for(i in [1,2,3,4,5,6]){ sum =+ i } //对map进行循环 for(i in ['lili':1,'luck':2]){ sum += i.value }
groovy闭包讲解
基础
概念
- 定义 及以个代码块
def clouser = {println 'Hello Groovy'}
- 调用
1
2
3
4
5
6
7
8
9
10
11
12
13def clouser0 = {println 'Hello Groovy'} clouser0() clouser0.call() def clouser = { String name -> println "Hello ${name}"} clouser.call("groovy"); def name = 'grovvy' clouser(name); def clouser1 = { String name1,int age -> println "Hello ${name},My age is ${age}"} clouser1('jiaozhenzhen',30); //隐式参数it def clouser2 = {println "Hello ${it}"} clouser2("chengcheng")
参数
- 普通参数
- 隐式参数
闭包返回值:总是有返回值的
1
2
3
4
5
6
7
8def closer = {return "Hello ${it}"} def result = closer('groovy') println result def closer1 = {println "Hello ${it}"} def result1 = closer1('groovy') println result1 //null
使用
与基本类型结合使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24//求阶乘 int fac(int number) { int result = 1; 1.upto(number){ num -> result *= num } return result } //求阶乘 int fac2(int number){ int result = 1; number.downto(1,{num -> result *= num}) return result } println fac2(5); //求1-100的和 int toSum(int number) { int result = 0 number.times {num -> result += num} return result } println toSum(101);
闭包怎么写要参考方法内部闭包的调用
String
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23def str= 'the 2 and 3 is 5' //each遍历 str.each { String i -> print i.multiply(2)//每次打印两个 }//tthhee 22 aanndd 33 iiss 55 //find查找符合条件的第一个字符 def n = str.find { String s -> s.isNumber() } println n //2 //findAll def list = str.findAll {String s -> s.isNumber()} //[2, 3, 5] println list //any 只要有一处满足即返回true def r = str.any {String s -> s.isNumber()} println r //true //every 只有都满足情况才返回true def everyr = str.every {String s -> s.isNumber()} println everyr; //collect 对每个字符进行闭包处理在进行收集 def list2 = str.collect {it.toUpperCase()} println list2
数据结构
文件等
进阶
闭包的关键变量
this
owner
delegate
1
2
3
4
5
6
7def scriptClouser = { println "scriptClouser this:" + this //代表闭包定义处的类的对象 GroovyScript在编译后会生成一个集成Scprit的一个类 println "scriptClouser owner:" + owner//代表闭包定义处的类的对象或者拥有者的对象 闭包可以定义在闭包中,此时owner代表的是外层闭包 println "scriptClouser delegate:" + delegate//代表任意对象,默认与owner一致,可以对其进行修改(this和owner是不可以修改的) } scriptClouser.delegate = ...
闭包的委托策略
修改委托后有时还需要修改一下委托策略
1
2
3
4
5
6Student stu = new Student(name: "张三"); Teacher tea = new Teacher(name: "李四") stu.callName.delegate = tea stu.callName.resolveStrategy = Closure.DELEGATE_FIRST println stu.toString()
委托策略有
public static final int OWNER_FIRST = 0; //优先查找当前owner
public static final int DELEGATE_FIRST = 1;//优先查找代理对象
public static final int OWNER_ONLY = 2;
public static final int DELEGATE_ONLY = 3;
public static final int TO_SELF = 4;
groovy数据结构
grovvy 列表
列表的定义
1
2
3
4
5def list = [1,2,3,4,5] println list.class //ArrayList def groovyArray = [1,2,3,4,5] as int[] // 定义数组 int[] array = [2,3,4] //定义数组
列表的操作
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
26def sortList = [2,1,4,7,3,8,-9] //sortList.sort() //println sortList sortList.sort {a,b -> a == b ? 0: Math.abs(a) > Math.abs(b) ? 1 :-1 } println sortList def sortString = ['abc','z','Hello','groovy','java'] sortString.sort {return it.size()} println sortString def list = [2,1,4,7,3,8,-9] //find 查找 def a = list.find{return it % 2 == 0} //findAll def b = list.findAll {return it % 2 == 0} //every def c = list.every {return it > 0} //any def d = list.any{return it >0} //min() def e = list.min() def f = list.min {return Math.abs(it)} //max() //count def g = list.count {return it % 2 == 0 }
groovy 中映射的详解
定义
定义时,key值要定义成单引号的不可变字符串,不加单引号时,编译器会编译成不可变字符串
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84def colours = [red : 'ff0000',green:'ooffoo',yellow:'cc222'] //默认的定义的是LinkedHashMap //查找 println colours['red'] //不能使用colours.class 因为不确定是key还是class println colours.red //添加 colours.blue = 'fffff000'//同样也是修改 println colours.toMapString() //删除 remove //遍历 def students = [ 1:[number:'001', name:'Boo', score:55, sex:'male' ], 2:[number:'002', name:'Johnny', score:62, sex:'female' ], 3:[number:'003', name:'Claire', score:73, sex:'female' ], 4:[number:'004', name:'Amy', score:66, sex:'male' ] ] students.each {def student -> println student.key println student.value } students.eachWithIndex{ def student, int index -> println "index is ${index},the key is ${student.key}, the value is ${student.value}" } students.each{key,value -> println "the key is ${key},the value is ${value}" } //查找 def entry = students.find {def student -> return student.value.score >= 60 } println entry def entrys = students.findAll {def student -> return student.value.score >= 60 } def count = students.count { def student -> return student.value.score >=60 && student.value.sex == 'male' } //收集及格的姓名 def names = students.findAll {def student -> return student.value.score >= 60} .collect {return it.value.name} //是一个list println names def groups = students.groupBy { def student -> return student.value.score >= 60 ? '及格' : '不及格' } //排序 def sort = students.sort { student1, student2 -> Number num1 = student1.value.score Number num2 = student2.value.score return num1 == num2 ? 0 :num1 > num2 ? -1 : 1 } //返回的是新的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
27
28
29
30
31
32
33
34
35def range = 1..10 def one = range[0] boolean flag = range.contains(10) def from = range.from //开始值 def to = range.to //结束值 //Range 其实是List的子类 //遍历 range.each { println it } for(i in range){ println i } //在Swith。。Case中的使用 println getGrade(91) def getGrade(Number score){ def result switch (score){ case 0..<60: result = '不及格' break case 60..<80: result = '及格' break case 80..<90: result = '中等' break case 90..100: result = '优秀' } return result }
groovy面向对象
类,接口等
1
2
3
4
5
6
7
8//类 //所用类型默认都是public def person = new Person(name:'zhangsan',age:26); person.age//无论使用.property还是get方法,实际上都是调用get方法 //接口 接口中不能定义非public的方法 //trait 和接口和抽象类相似,但可以有实现的方法
1
2
3
4
5
6
7
8trait DefaultTrait { abstract void eat()//抽象方法需要使用abstract关键字 void smile(){ println '笑' } }
元编程
MetaClass类
methodMissing方法
invokeMethod方法
当调用方法不存在是会调用定义的,invokeMethod(String methodName,Object param[])
当重写了methodMissing(String name,Object args),调用不存在时调用本方法,优先级比invokeMethod方法
MetaClass类可以为类提供默认属性,使用Person.address = '..',即动态的设置属性(默认值)
为类添加方法Person.mataClass.sexUpperCase = {-> sex.toUpperCase()}
为类添加静态方法Person.mataClass.static.name = {...-> sex.toUpperCase()}
一般情况下,通过动态添加的方法和属性不能在其他代码中使用,若想要使用可以添加代码
ExpandoMetaClass.enableGlobally()
高级语法
对json的操作
转化为json
1
2
3
4def json = JsonOutput.toJson(...); JsonOutput.prettyprint(json)
1
2
3def jsonParse = new JsonSlurper(); jsonSlpuer.parse(obj);
对xml文件的操作
解析xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18def xmlSluper = new XmlSlurper();或者xmlParser def response = xmlSluper.parserText(xml); println response.value.books[0].book[0].title.text(); println response.value.books[1].book[0].@id //@制定属性 response.value.book.each{books -> books.book.each{book -> def author = bool.author.text() println book.name.text() } } //深度遍历 response.depthFirst().findAll{book -> def author = bool.author.text() println book.name.text()} 广度遍历 reponse.value.books.children().findAll{}
生产xml
1
2
3
4
5
6
7
8
9
10
11def sw = new StringWriter(); def xmlBuilder = new MarkupBuilder(sw);//生产xml数据的核心类 xmlBuilder.langs.(type:'current'...属性){ language(flavor:'static',java(值)) //按对象生产xml文档 xmlBuilder.langs(type:xx){ list.each{ } }
对文件的操作
文件的获取
1
2
3
4
5
6
7
8
9
10
11
12file.eachline{line->} file.getText() file.readLines();生成一个字符串的集合 file.withReader{reader -> char[] buffer = new char[100] reader.read(buffer) return burrer }
文件的写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24file.withReader{ writer ->{} } def copy(String sourcePath,String destationPath){ try{ def desFile = new File(destationPath) if(!desFile.exists){ desFile.createNewFile(); } new File(sourcePath).withReader{reader -> def lines = reader.readLines() desFile.withWiter{writer -> lines.each{line -> writer.append(line) } } } return true }catch(Exception e){ e.printStackTrace() } }
GRADLE
主要组成:groovy,build script block,gradle api
流程
initialization-> configuration ->Execution
gradle生命周期
project相关api
1
2
3
4
5
6
7
8
9
10/*Project 相关API,在build.gradle中书写*/ //1,this.getAllprojects():获取所有project this.getAllprojects() //2,this.getSubprojects():获取子project this.getSubprojects() //3,this.getParent():获取父project this.getParent() //this.getRootProject():获取根project this.getRootProject()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//对project做操作,'app'为相对路径 project('app'){ project ->{ apply plugin:"com.android.app" } } //对所有的工程操作(配置当前及子工程) allprojects { } //获取project project('路径') //对子工程操作 subprojects { Project project ->{ if(project.plugins.hasPlugin('com.android.library')){ apply from: "../pulishToMaven.gradle" } } }
task相关api
projects是一个task,可通过gradle projects
属性相关api
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//定义属性 def ver= '0.0.1' version = ver //扩展属性 //扩展代码块 ext{ compileSdkVersion = 25 } android{ compileSdkVersion this.compileSdkVersion } //ext{} subprojects{ ext{ compileSdkVersion = 25 libAndroidDesign = 'com.android.support:design:25.0.0' } } //ext定义在RootProject中 子工程中使用this.rootProject.属性,或this.属性(根工程的属性会被子工程继承) //最佳:在外部定义*.gradle,在内部定义ext{} apply from: this.file('commom.gradle')
1
2
3
4
5
6//扩展属性的其他定义方式 //定义在gradle.properties中 if(hasProperty('isLoadTest') ? isLoadTest.toBoolean() : false){ include ':Test' }
file相关api
路径获取相关API
1
2
3
4
5
6
7//1 getRootDir() 获取根目录 println "the root file path is:" + getRootDir().absolutePath //2 getBuildDir() 当前工程的的build文件夹 println "the build file path is :" +getBuildDir().absolutePath //3 getProjectDir() 当前工程的文件夹 println "the project file path is :" +getProjectDir().absolutePath
文件操作相关API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//文件定位 相对路径相对于当前工程 file('path') //文件定位 files(String...path)//多文件定位 copy{//文件拷贝 from file('') into getRootProject().getBuildDir().path + "/apk" exclude{} rename{} } //对文件树进行遍历 fileTree("/build/outputs/apk/"){ FileTree fileTree -> fileTree.visit{ FileTreeElement element -> println element.file.name } }
其他api
依赖相关api
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
33dependencies{ compile fileTree(include:['*.jar'],dir:'libs')//本地的lib文件 compile com.... 引用第三发jar{ exclude module: 'support-4'或 exclude group:'com.android.support'//排除依赖 transive false //禁止传递依赖,一般情况下不要使用传递依赖 } compile project('path') 引用工程 } buildscript{ ScriptHandler scriptHandler -> //工程的仓库地址 repositories{RepositoryHandler handler -> mavenCentral() mavenLocal() maven{ name 'personal' url 'http...' credentials{ username = 'amdin' password = 'admin123' } } } //grade对插件的依赖,而不是应用程序 dependencied{} }
外部命令执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19task('apkcopy'){ doLast{ def sourcePath = '' def desationPath = '' def command = "mv -f ${sourcePath} ${desationPath}" exec{ try{ executable 'bash' args '-c' ,command //唯一会变的是command println 'exec is success' }catch(GradleException e){ print 'the command is excute failded ' } } } } }
Task
Task定义及配置
定义
1
2
3
4
5
6
7task helloTask{ print 'i am helloTask' } this.tasks.create(name:'helloTask2'){//用taskContainer管理task println 'i am helloTask2' }
配置
1
2
3
4
5
6
7
8task helloTask(group:'imooc',description:'task Study'){}//在定义的时候配置,推荐 this.tasks.create(name:'helloTask2'){//用taskContainer管理task setGroup('imooc') setDescription('task Study2') println 'i am helloTask2'//在配置阶段执行 }
Task的执行详解
1
2
3
4
5
6
7
8
9
10
11
12task helloTask(group:'imooc',description:'task Study'){ doFirst{ }//在执行阶段执行 doLast{ }//在执行阶段执行 } helloTask.doFirst{} //外部的先执行,闭包内部的后执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14def startBuildTime,endBuildTime this.afterEvaluate{ Project project //配置后,保证task已经配置完成 def preBuildTask = project.tasks.getByName('preBuild') preBuildTask.doFirst{ startBuildTime = System.currentTimeMillis(); } def buildTask = project.tasks.getByName('build') buildTask.doLast{ endBuildTime = System.currentTimeMillis(); println "the build thim is ${endBuildTime - startBuildTime}" } }
Task的依赖和执行顺序
dependsOn 强依赖方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23task taskX{ doFirst { println 'taskX' } } task taskY{ doFirst { println 'taskY' } } task taskZ(dependsOn: [taskX,taskY]){ dependsOn this.tasks.findAll{ task -> task.name.startsWith('lib')//动态依赖1️以lib开头的task } doFirst { println 'taskZ' } } //taskZ.dependsOn(taskX,taskY) //此时taskX和taskY的顺序并不确定
最后
以上就是傻傻白开水最近收集整理的关于Gradle使用说明Groovy 概述Groovy 语法详解高级语法GRADLETask的全部内容,更多相关Gradle使用说明Groovy内容请搜索靠谱客的其他文章。
发表评论 取消回复