Gradle學(xué)習(xí)筆記(三)-- Groovy常用類(lèi)介紹

前言

在學(xué)習(xí)Gradle時(shí),首先要對(duì)Groovy這個(gè)腳本語(yǔ)言的常用的東西有個(gè)概念,以后也好閱讀別人的腳本或者自己寫(xiě)插件。

Groovy中的基本數(shù)據(jù)類(lèi)型

數(shù)據(jù)類(lèi)型可以在Groovy Api 在線文檔的lang包下看到,大致有以下三類(lèi):

1. java中的基本類(lèi)型
2. 容器類(lèi)型(List ,Map,Range)
3. 閉包
  • List
    類(lèi)似ArrayList , def alist = ['a',1,true]; alist[1] == 1; alist.size == 3
  • Map
    類(lèi)似LinkedHashMap,def amap = ['key1':value1,'key2':value2];
  • Range
    對(duì)List的擴(kuò)展
    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

在閉包的學(xué)習(xí)中,有以下需要注意的地方:

  • it
    如果閉包沒(méi)定義參數(shù)的話,則隱含有一個(gè)參數(shù),這個(gè)參數(shù)名字叫 it ,和 this 的作用類(lèi)似。it 代表閉包的參數(shù)。
  • 省略圓括號(hào)
    閉包在 Groovy 中大量使用,比如很多類(lèi)都定義了一些函數(shù),這些函數(shù)最后一個(gè)參數(shù)都
    是一個(gè)閉包。比如:
public static <T> List<T> each(List<T> self, Closure closure)

上面這個(gè)函數(shù)表示針對(duì)List的每一個(gè)元素都會(huì)調(diào)用closure做一些處理。這里的closure,
就有點(diǎn)回調(diào)函數(shù)的感覺(jué)。但是,在使用這個(gè) each 函數(shù)的時(shí)候,我們傳遞一個(gè)怎樣的 Closure
進(jìn)去呢?比如:

def iamList = [1,2,3,4,5] //定義一個(gè) List
iamList.each{ //調(diào)用它的 each,這段代碼的格式看不懂了吧?each 是個(gè)函數(shù),圓括號(hào)去哪了?
          println it
}

上面代碼有兩個(gè)知識(shí)點(diǎn):
each 函數(shù)調(diào)用的圓括號(hào)不見(jiàn)了!原來(lái),Groovy 中,當(dāng)函數(shù)的最后一個(gè)參數(shù)是閉包的話,可以省略圓括號(hào)。比如

def testClosure(int a1,String b1, Closure closure){
       //do something
        closure() //調(diào)用閉包
}
那么調(diào)用的時(shí)候,就可以免括號(hào)!
testClosure   4, "test", {
         println "i am in closure"
} 

省略圓括號(hào)雖然使得代碼簡(jiǎn)潔,看起來(lái)更像腳本語(yǔ)言,但是它這經(jīng)常會(huì)讓我 confuse(不知道其他人是否有同感),以 doLast 為例,完整的代碼應(yīng)該按下面這種寫(xiě)法:

doLast({
      println 'Hello world!'
})

有了圓括號(hào),你會(huì)知道 doLast 只是把一個(gè) Closure 對(duì)象傳了進(jìn)去。很明顯,它不代表這段腳本解析到 doLast 的時(shí)候就會(huì)調(diào)用 println 'Hello world!' 。但是把圓括號(hào)去掉后,就感覺(jué)好像 println 'Hello world!'立即就會(huì)被調(diào)用一樣!

  • 如何確定 Closure 的參數(shù)
    另外一個(gè)比較讓人頭疼的地方是,Closure 的參數(shù)該怎么搞?還是剛才的 each 函數(shù):
public static <T> List<T> each(List<T> self, Closure closure)

each 函數(shù)說(shuō)明中,將給指定的 closure 傳遞 Set 中的每一個(gè) item。所以,closure的參數(shù)只有一個(gè)。
findAll 中呢,就不知道該怎么辦了。一個(gè)是沒(méi)說(shuō)明往 Closure 里傳什么。另外沒(méi)說(shuō)明 Closure的返回值是什么.....。
Closure 雖然很方便,但是它一定會(huì)和使用它的上下文有極強(qiáng)的關(guān)聯(lián)。要不,作為類(lèi)似回調(diào)這樣的東西,我如何知道調(diào)用者傳遞什么參數(shù)給 Closure 呢?此問(wèn)題如何破解?只能通過(guò)查詢(xún) API 文檔才能了解上下文語(yǔ)義。所以最初階段,SDK 查詢(xún)是必不可少的。

文件IO和XML操作

文件讀寫(xiě):File

def targetFile = new File(文件名) <==File 對(duì)象還是要?jiǎng)?chuàng)建的。

看看 Groovy 定義的 API:

1 讀該文件中的每一行:eachLine 的唯一參數(shù)是一個(gè) Closure。Closure 的參數(shù)是文件每一行的內(nèi)容
其內(nèi)部實(shí)現(xiàn)肯定是 Groovy 打開(kāi)這個(gè)文件,然后讀取文件的一行,然后調(diào)用 Closure...

    targetFile.eachLine{
        String oneLine ->
        println oneLine
    } <==是不是令人發(fā)指??!

2 直接得到文件內(nèi)容
    targetFile.getBytes() <==文件內(nèi)容一次性讀出,返回類(lèi)型為 byte[]
   //注意前面提到的 getter 和 setter 函數(shù),這里可以直接使用 targetFile.bytes....

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

4 使用閉包操作 inputStream,以后在 Gradle 里會(huì)??吹竭@種搞法
    targetFile.withInputStream{ ism ->
       操作 ism. 不用 close。Groovy 會(huì)自動(dòng)替你 close
    }

5 寫(xiě)文件
    def srcFile = new File(源文件名)
    def targetFile = new File(目標(biāo)文件名)
    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模型常用數(shù)據(jù)類(lèi)型

  • Project

    映射到build.gradle文件,從Project你可以獲取Gradle的所有features,其中主要的Method如下:
Project Method 1
Project Method 2
Project Method 3

Project Method 4
  • Task

    一個(gè)工程是很多個(gè)Tasks的集合,每個(gè)Task都會(huì)有一個(gè)基本的獨(dú)特的功能,或者單元測(cè)試,或者單純的打一個(gè)jar包。
    在script中可以這樣定義Task:

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

TaskContainer包含了所有的task任務(wù),我們可以通過(guò)在Project中的getTasks().findByPath('packageReleaseJniLibs')來(lái)獲取特定名字的task,然后可以通過(guò)dependsOn,mustRunAfter 等來(lái)插入自己定義的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對(duì)象實(shí)例,通過(guò)[Project.getGradle()](https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#org.gradle.api.Project:gradle)可以 獲取。我們需要重點(diǎn)關(guān)注下其中的method方法,對(duì)于我們定制化有很大的意義。

![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)
簡(jiǎn)單來(lái)說(shuō),Script 是一個(gè)接口,Gradle中的腳本會(huì)implement這個(gè)接口并實(shí)現(xiàn)自己的功能,并且每個(gè)Script都會(huì)有個(gè)Groovy對(duì)象相應(yīng),例如一個(gè) build   script 對(duì)應(yīng)一個(gè)project,一個(gè)init script 對(duì)應(yīng)一個(gè)Gradle 對(duì)象。在此Script對(duì)象上找不到的任何屬性引用或方法調(diào)用都將轉(zhuǎn)發(fā)到委托對(duì)象。
#參考
* [Groovy Api 在線文檔](http://www.groovy-lang.org/api.html)
* [Gradle Api 在線文檔](https://docs.gradle.org/current/javadoc/)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 導(dǎo)語(yǔ): 隨著技術(shù)的發(fā)展,不管是前端開(kāi)發(fā)、服務(wù)端開(kāi)發(fā)或者是移動(dòng)端開(kāi)發(fā)(移動(dòng)也是前端的一個(gè)分支)中都會(huì)用到自動(dòng)化構(gòu)建工...
    伊始雨深閱讀 3,153評(píng)論 0 4
  • Groovy :是一種動(dòng)態(tài)語(yǔ)言。 1:這種語(yǔ)言比較有特點(diǎn),它和 Java 一樣,也運(yùn)行于 Java 虛擬機(jī)中。簡(jiǎn)單...
    PeytonWu閱讀 1,677評(píng)論 0 1
  • 這篇文章講給大家?guī)?lái)gradle打包系列中的高級(jí)用法-自己動(dòng)手編寫(xiě)gradle插件。我們平常在做安卓開(kāi)發(fā)時(shí),都會(huì)在...
    呆萌狗和求疵喵閱讀 16,340評(píng)論 22 80
  • Gradle對(duì)于很多開(kāi)發(fā)者來(lái)說(shuō)有一種既熟悉又陌生的感覺(jué),他是離我們那么近,以至于我每天做項(xiàng)目都需要他,但是他又是離...
    阿_希爸閱讀 9,716評(píng)論 10 199
  • 都說(shuō)父愛(ài)如山,沉默而偉大。我卻說(shuō)父愛(ài)像傘,無(wú)論風(fēng)中雨中,都為我們撐起了一片天。端午節(jié)過(guò)后就是父親節(jié),你是否想過(guò)...
    樓蘭燃雪閱讀 366評(píng)論 0 1

友情鏈接更多精彩內(nèi)容