Gradle基礎

配置Gradle環境

前提:配置好Java環境
把gradle 對象的bin目錄配置到系統環境變量裏面

這裏寫圖片描述

出現如下圖,則表示環境已經配置好了

這裏寫圖片描述

Gradle版 hello world

創建一個build.gradle文件

添加gradle版的hello world腳本代碼

task hello{
    doLast{
        println 'hello world'
    }
}

在控制檯輸入如下命令,編譯完成後會出現hello world字符,正是我們println輸出的
這裏寫圖片描述

build.gradle是Gradle默認的構造腳本文件,執行gradle命令的時候,會默認加載當前目錄下的build.gradle腳本文件
這個構建腳本定義一個任務,這個任務名字叫hello,並且給任務hello添加了一個Action,它其實就是一段Groovy語言實現的閉包。doLast就意味着在Tast執行完畢後要回調doLast的這部分閉包的代碼
再看gradle -q hello這個命令,意思是要執行build.gradle腳本中定義的名爲hello的Task,-q 參數用於控制gradle輸出的日誌級別,以及哪些日誌可以輸出被看到。
如果不加-q命令,如下

這裏寫圖片描述

是不是有點類型我們的android studio裏面的EventLog裏面的日誌
看到println ‘hello world’,它會輸出hello world,通過名字大家已經猜出來,它其實就是System.out.println(“hello world”)的簡寫方法,Gradle可以識別它,是因爲Groovy已經把println()這個方法添加到java.lang.Object,而在Groovy中,方法的調用可以省略簽名中的括號,以一個空格分開即可,所以就有了上面的寫法。說明的是,在Groovy中,單引號和雙引號所包含的內容都是字符串

Gradle 日誌

前面我們通過-q參數控制命令,Gradle的日誌級別還有其他類型,如下

這裏寫圖片描述

要使用它們,則通過命令行參數開關控制

這裏寫圖片描述

輸出錯誤堆棧信息 ,默認情況堆棧信息的輸出是關閉的,我們可以同如下參數打開它。這樣在我們構建失敗的時候,Gradle纔會輸出錯誤堆棧信息

這裏寫圖片描述

使用自己的日誌調試,如果我們需要輸出一些日誌,通常情況下我們使用print系列方法,把日誌信息輸出到標準的控制檯輸出流

printl ‘輸出一個日誌信息’

除了print系列方法,也可以使用內置的logger更靈活的控制輸出不同級別的日誌信息:

logger.quiet(‘message’)
logger.error(‘message’)
logger.warn(‘message’)
logger.lifecycle(‘message’)
logger.info(‘message’)
logger.debug(‘message’)

這裏其實是調用Project的getLogger()方法阿獲取Logger對象的實例

Groovy 基礎

Groovy是基於JVM虛擬機的一種動態語言,語法和Java相似,完全兼容Java,又在此基礎上增加了很多動態類型和靈活的特性,比如支持閉包,支持DSL,可以說它是一門非常靈活的動態腳本語言
每個Gradle的build腳本文件都是一個Groovy腳本文件,你可以在裏面寫任何符號Groovy語法的代碼,而Groovy又完全兼容Java,所有你也可以在build腳本文件裏面寫任何Java代碼

字符串

添加代碼,

task printlnStr <<{
def str1='單引號'
def str2='雙引號'

println '單引號類型:'+str1.getClass().name
println '雙引號類型:'+str2.getClass().name

def name="張三"
println '單引號變量:${name}'
println "雙引號變量:${name}"
}

輸出日誌,可以看到單引號和雙引號都是String類型,但是單引號不能對字符串裏面的表達式做運算,雙引號可以直接進行表達式計算,一個美元符號緊跟一對花括號,花括號裏面放表達式,如何name, {1+1}等,只有一個變量的時候可以省略花括號,如$name

這裏寫圖片描述

通常我們在app 的build.gradle 也常常看到,如下,我們就知道SUPPORTVERSION就是一個變量,並且這裏不能用單引號表示

implementation "com.android.support:appcompat-v7:$SUPPORTVERSION"
implementation "com.android.support:cardview-v7:$SUPPORTVERSION"

集合

Groovy完全兼容了Java的集合,並且進行了擴展

List

定義一個List,訪問List集合

task printList <<{
    def numList=[1,2,3,4,5];
    println numList.getClass().name

    println numList[1] //訪問第二個元素
    println numList[-1] //訪問最後一個元素
    println numList[1..3] //訪問第二個元素到第四個元素
    numList.each{
            println it
        }
}

輸出,可以看到numList是一個ArrayList類型,訪問方式也多種,其中each方法可以方便的迭代操作,該方法接收一個閉包作爲參數,可以訪問List裏面的每個元素

這裏寫圖片描述

定義一個Map,訪問Map集合

task printMap <<{
    def map=['w':123,'h':456];
    println map.getClass().name

    println map['w'] 
    println map.h 

    map.each{
        println "key:${it.key},value:${it.value}"
    }
}

這裏寫圖片描述

方法

這個是重點了

在Java裏面調用方法是method(parm1,parm2),而在Groovy裏面,可以省略(),變成method parm1,parm2

代碼

task testMethod <<{
    add(1,2)
    add 1,2
}
def add(int a,int b){
    println a+b 
}

輸出
這裏寫圖片描述

return可以不寫 ,Groovy中,定義有返回值的方法時,return 語句不是必需的,當沒有return時候,最後一句代碼作爲返回值

代碼

task testMethod <<{
    add(1,2)
    add 1,2
    def result=method2 1,2
    println "result:$result";
}
def add(int a,int b){
    println a+b 
}

def method2(int a,int b){
    a+b
}

輸出
這裏寫圖片描述

代碼塊可以作爲參數傳遞,代碼塊–一段被花括號包圍的代碼,也就是閉包。Groovy允許其作爲參數傳遞

以上面集合each方法爲例子,調用集合的each方法,傳入代碼塊

numList.each({
    println it
})
//Groovy規定,如果方法的最後一個參數是閉包,可以方法方法外面
numList.each(){
    println it
}
//由於方法參數括號可以省略,因此變成這樣的樣式
numList.each{
    println it
}

閉包

前面說過閉包就是一段代碼塊,下面我們先自己寫一個閉包。我們定義了一個方法customEach,它只有一個參數用於接收一個閉包,那麼閉包怎麼執行呢?調用方法的時候後面跟一對括號就是執行了。
括號裏的參數就是該閉包接收的參數,

如果參數只有一個,那麼就是it變量

task testClosure <<{
    customEach{
        println it
    }
}
def customEach(closure){
    for(int i in i..10){
        closure(i)
    }
}

輸出
這裏寫圖片描述

多個參數,當閉包只有一個參數是,默認就是it,當有多個參數時,就需要把參數一一列出

task testClosure2 <<{
    eachMap{
        k,v -> println "${k} is ${v}"
    }
}
def eachMap(closure){
    def map=['w':123,'h':456];
    map.each{
        closure(it.key,it.value)
    }
}

這裏寫圖片描述

像我們平常要更改生成APP的名稱,在後面添加版本號。會在build.gradle添加如下代碼,現在我們知道執行的是applicationVariants的all方法,後面是一個閉包,閉包裏面有個variant變量,而variant的outputs.add方法也是有一個閉包,執行的就是我們修改輸出app的apk包名

//在apk文件後邊生成版本號信息
applicationVariants.all {
    variant ->
        variant.outputs.add {
            outputFileName = new File(output.outputFile.parent, "app_" + "V" + defaultConfig.versionName + ".apk");
        }
}

閉包委託

Groovy閉包的強大之處在於它之處閉包方法的委託,閉包有thisObject,owner,delegate三個屬性,當你再閉包內調用方法時,由它來確定使用哪個對象來處理。默認情況下deletgate和owner是相等的,但是delegate是可以被修改。

示例代碼,定義了一個方法person。設置了委託對象爲當前創建的Person實例,並且設置了委託模式優先,所以,我們在使用person方法創建一個Person的實例時,可以在閉包裏直接對該Person實例配置。

task configClosure <<{

    person{
        name="張三"
        age=18
        dumpPerson()
    }

}
class Person{
    String name
    int age
    def dumpPerson(){
        println "name is ${name},age is ${age}"
    }

}
def person(Closure<Person> closure){
    Person p=new Person()
    closure.delegate=p
    //委託模式優先
    closure.setResolveStrategy(Closure.DELEGATE_FIRST)
    closure(p)
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章