Gradle学习笔记(三)-- Groovy常用类介绍

前言

在学习Gradle时,首先要对Groovy这个脚本语言的常用的东西有个概念,以后也好阅读别人的脚本或者自己写插件。

Groovy中的基本数据类型

数据类型可以在Groovy Api 在线文档的lang包下看到,大致有以下三类:

1. java中的基本类型
2. 容器类型(List ,Map,Range)
3. 闭包
  • List
    类似ArrayList , def alist = ['a',1,true]; alist[1] == 1; alist.size == 3
  • Map
    类似LinkedHashMap,def amap = ['key1':value1,'key2':value2];
  • Range
    对List的扩展
    IntRange :Represents a list of Integer objects from a specified int up (or down) to and including a given to
    ObjectRange:Represents an inclusive list of objects from a value to a value using comparators.
    def arange = 1..5 //表示1,2,3,4,5
    def arange = 1..<5//表示1,2,3,4
  • Closure
    闭包的定义:
 def a = 1
 def c = { a }
 assert c() == 1
//或者
 def a = 1
 def c = {a}
 assert c.call() == 1

在闭包的学习中,有以下需要注意的地方:

  • it
    如果闭包没定义参数的话,则隐含有一个参数,这个参数名字叫 it ,和 this 的作用类似。it 代表闭包的参数。
  • 省略圆括号
    闭包在 Groovy 中大量使用,比如很多类都定义了一些函数,这些函数最后一个参数都
    是一个闭包。比如:
public static  List each(List self, Closure closure)

上面这个函数表示针对List的每一个元素都会调用closure做一些处理。这里的closure,
就有点回调函数的感觉。但是,在使用这个 each 函数的时候,我们传递一个怎样的 Closure
进去呢?比如:

def iamList = [1,2,3,4,5] //定义一个 List
iamList.each{ //调用它的 each,这段代码的格式看不懂了吧?each 是个函数,圆括号去哪了?
          println it
}

上面代码有两个知识点:
each 函数调用的圆括号不见了!原来,Groovy 中,当函数的最后一个参数是闭包的话,可以省略圆括号。比如

def testClosure(int a1,String b1, Closure closure){
       //do something
        closure() //调用闭包
}
那么调用的时候,就可以免括号!
testClosure   4, "test", {
         println "i am in closure"
} 

省略圆括号虽然使得代码简洁,看起来更像脚本语言,但是它这经常会让我 confuse(不知道其他人是否有同感),以 doLast 为例,完整的代码应该按下面这种写法:

doLast({
      println 'Hello world!'
})

有了圆括号,你会知道 doLast 只是把一个 Closure 对象传了进去。很明显,它不代表这段脚本解析到 doLast 的时候就会调用 println 'Hello world!' 。但是把圆括号去掉后,就感觉好像 println 'Hello world!'立即就会被调用一样!

  • 如何确定 Closure 的参数
    另外一个比较让人头疼的地方是,Closure 的参数该怎么搞?还是刚才的 each 函数:
public static  List each(List self, Closure closure)

each 函数说明中,将给指定的 closure 传递 Set 中的每一个 item。所以,closure的参数只有一个。
findAll 中呢,就不知道该怎么办了。一个是没说明往 Closure 里传什么。另外没说明 Closure的返回值是什么.....。
Closure 虽然很方便,但是它一定会和使用它的上下文有极强的关联。要不,作为类似回调这样的东西,我如何知道调用者传递什么参数给 Closure 呢?此问题如何破解?只能通过查询 API 文档才能了解上下文语义。所以最初阶段,SDK 查询是必不可少的。

文件IO和XML操作

文件读写:File

def targetFile = new File(文件名) <==File 对象还是要创建的。

看看 Groovy 定义的 API:

1 读该文件中的每一行:eachLine 的唯一参数是一个 Closure。Closure 的参数是文件每一行的内容
其内部实现肯定是 Groovy 打开这个文件,然后读取文件的一行,然后调用 Closure...

    targetFile.eachLine{
        String oneLine ->
        println oneLine
    } <==是不是令人发指??!

2 直接得到文件内容
    targetFile.getBytes() <==文件内容一次性读出,返回类型为 byte[]
   //注意前面提到的 getter 和 setter 函数,这里可以直接使用 targetFile.bytes....

3 使用 InputStream.InputStream 的 SDK 在http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/InputStream.html
    def ism = targetFile.newInputStream()
    //操作 ism,最后记得关掉
    ism.close

4 使用闭包操作 inputStream,以后在 Gradle 里会常看到这种搞法
    targetFile.withInputStream{ ism ->
       操作 ism. 不用 close。Groovy 会自动替你 close
    }

5 写文件
    def srcFile = new File(源文件名)
    def targetFile = new File(目标文件名)
    targetFile.withOutputStream{ os->
                srcFile.withInputStream{ ins->
              os << ins //利用 OutputStream 的<<操作符重载,完成从 inputstream 到 OutputStream的输出
    }
}

Xml解析: GPathResult,XmlSlurper

  def androidManifest = new XmlSlurper().parse("AndroidManifest.xml")
  println androidManifest['@android:versionName']
  或者
  println androidManifest.@'android:versionName'

Gradle模型常用数据类型

  • Project

    映射到build.gradle文件,从Project你可以获取Gradle的所有features,其中主要的Method如下:
Gradle学习笔记(三)-- Groovy常用类介绍_第1张图片
Project Method 1
Gradle学习笔记(三)-- Groovy常用类介绍_第2张图片
Project Method 2
Gradle学习笔记(三)-- Groovy常用类介绍_第3张图片
Project Method 3

Gradle学习笔记(三)-- Groovy常用类介绍_第4张图片
Project Method 4
  • Task

    一个工程是很多个Tasks的集合,每个Task都会有一个基本的独特的功能,或者单元测试,或者单纯的打一个jar包。
    在script中可以这样定义Task:

task myTask
task myTask { configure closure }
task myTask(type: SomeType)
task myTask(type: SomeType) { configure closure }

TaskContainer包含了所有的task任务,我们可以通过在Project中的getTasks().findByPath('packageReleaseJniLibs')来获取特定名字的task,然后可以通过dependsOn,mustRunAfter 等来插入自己定义的Task。
![Task Property](http://upload-images.jianshu.io/upload_images/22193-bdbbf35b7272fc29.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* [Gradle
](https://docs.gradle.org/current/dsl/org.gradle.api.invocation.Gradle.html)
Gradle对象实例,通过[Project.getGradle()](https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:gradle)可以 获取。我们需要重点关注下其中的method方法,对于我们定制化有很大的意义。

![Gradle的methods 1](http://upload-images.jianshu.io/upload_images/22193-4e667cb4f5a80037.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

![Gradle的methods 2](http://upload-images.jianshu.io/upload_images/22193-4b9a88adda38ed61.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* [Settings
](https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html)
映射到settings.gradle文档
* [Script
](https://docs.gradle.org/current/dsl/org.gradle.api.Script.html)
简单来说,Script 是一个接口,Gradle中的脚本会implement这个接口并实现自己的功能,并且每个Script都会有个Groovy对象相应,例如一个 build   script 对应一个project,一个init script 对应一个Gradle 对象。在此Script对象上找不到的任何属性引用或方法调用都将转发到委托对象。
#参考
* [Groovy Api 在线文档](http://www.groovy-lang.org/api.html)
* [Gradle Api 在线文档](https://docs.gradle.org/current/javadoc/)

你可能感兴趣的:(Gradle学习笔记(三)-- Groovy常用类介绍)