Android Gradle—了解Gradle及自動化構(gòu)建

前言

本專欄內(nèi)容主要分為兩大部分:

  1. Groovy基礎(chǔ)到進階
  2. Gradle開發(fā)及Gradle在Android中的使用。

本專欄內(nèi)容盡量做到覆蓋全滿,不遺漏知識點。

  1. 對于Groovy的學(xué)習(xí)會基于已掌握的Java及Kotlin語言,通過對比分析來提高學(xué)習(xí)效率。
  2. 對于Gradle的內(nèi)容我們主要針對在Android開發(fā)中的實際使用來進行講解,做到學(xué)以致用的目的。

1. Gradle介紹

  • Gradle是一款基于Apache的Ant和Maven概念的項目自動化開源構(gòu)建工具。Gradle的核心是基于Java來實現(xiàn)的,可以把Gradle看成就是一個輕量級的Java應(yīng)用程序。
  • Gradle是使用Groovy、Kotlin等語言編寫自定義腳本,取代了Ant和Maven使用xml配置文件的方式,很大程度簡化了開發(fā)時對項目構(gòu)建要做的配置,使用更加靈活和強大。

1.1 為什么要學(xué)習(xí)Gradle

Gradle不僅是目前Andorid最主流的構(gòu)建工具。而且不少技術(shù)領(lǐng)域如組件化、插件化、熱修復(fù),及構(gòu)建系統(tǒng) (很多優(yōu)秀的框架都是在編譯時或者打包之前做一些特殊的處理) ,都需要通過Gradle來實現(xiàn),不懂Gradle將無法完成上述事情,所以學(xué)習(xí)Gradle非常必要。

1.2 關(guān)于項目構(gòu)建

  1. 對于Java應(yīng)用程序,編寫好的Java代碼需要編譯成.class文件才能夠執(zhí)行。所以任何的Java應(yīng)用開發(fā),最終都需要經(jīng)過這一步;
  2. 編譯好了這些class文件,還需要對其進行打包。打包不僅針對于這些class文件,還有所有的資源文件等。比如web工程打包成jar包或者war包就包含了自己的資源文件,然后放到服務(wù)器上運行。
  3. Andorid工程編譯好的class文件還要被打包到dex包中,并且所有的資源文件進行合并處理,甚至還需要對最終打包出來的文件進行加密和簽名處理等等。

圖解說明

1.3 自動化構(gòu)建工具的發(fā)展

  1. “石器時代”:自己編寫命令腳本,進行編譯和打包
  2. “蒸汽時代”:Make、Ant工具的出現(xiàn)
  3. “電氣時代”:Maven
  4. “信息時代”:Gradle,更高級的自動構(gòu)建工具出現(xiàn) ...

1.4 Gradle提供了什么

  • 對多工程的構(gòu)建支持非常出色,尤其是工程依賴問題,并支持局部構(gòu)建;
  • 多種方式的依賴管理:如遠(yuǎn)程Maven倉庫,nexus私服,ivy倉庫或者本地文件系統(tǒng)等;
  • 支持傳遞性依賴管理;
  • 輕松遷移項目工程;
  • 基于Groovy等語言構(gòu)建腳本,簡便且靈活;
  • 免費開源,并且整體設(shè)計是以作為一種語言為導(dǎo)向的,而非成為一個嚴(yán)格死板的框架。

上面我們提到, Gradle是使用Groovy、Kotlin等語言編寫自定義腳本,現(xiàn)在我們了解了Gradle相關(guān)的,接下來將介紹 Groovy。

2. Groovy介紹

Groovy是一種基于JVM(Java虛擬機)的敏捷開發(fā)語言,它結(jié)合了Python、Ruby和Smalltalk的許多強大的特性,Groovy代碼能夠與Java代碼很好地結(jié)合,也能用于擴展現(xiàn)有代碼。由于其運行在 JVM 上的特性,Groovy也可以使用其它非Java語言編寫的庫。

這里我們提到,Groovy代碼能夠與Java代碼很好地結(jié)合,然后現(xiàn)在Android開發(fā)也慢慢往 Kotlin 發(fā)展,那么我們看看這三者的區(qū)別。

2.1 Groovy & Java & Kotlin

  • Groovy、Java及Kotlin都是基于JVM的開發(fā)語言;
  • Groovy基于Java,在語法上基本相似,但也做了很多自己的擴展。Groovy除了可以面向?qū)ο缶幊蹋€可以用作純粹的腳本語言,這一點和Kotlin是一樣的;
  • Goovy 和 Kotlin都有自己支持的DSL,兩者有許多共通之處。

這里有一組比較有意思的對話:

Groovy:我不是針對Java,而是所有不能愉快寫DSL的都是laji。
Clojure:我真的不是針對Java,只是關(guān)于并發(fā),我有一個大膽的想法。
Scala:我也真的不是針對Java,只是關(guān)于并發(fā),我還有一種大膽的想法。
Kotlin:我就是處處針對Java!
Java退出了群聊...

滿滿感受到Java的無奈 :》

2.2 Groovy特性

  • 同時支持靜態(tài)類型和動態(tài)類型;
  • 支持運算符重載;
  • 支持DSL語法特性;
  • 本地語法列表和關(guān)聯(lián)數(shù)組;
  • 各種標(biāo)記語言,如XML和HTML原生支持;
  • 對正則表達式的本地支持;
  • Groovy和Java語法非常相似,可以無縫銜接使用Java;
  • 支持使用現(xiàn)有的Java庫,并做了一定的擴展。

這里說到,Groovy和Java語法非常相似,可以無縫銜接使用Java,那我們來看看是如何無縫銜接的。

3. 從Java到Groovy

注:開發(fā)環(huán)境為:Idea+Groovy環(huán)境,所以開發(fā)者需要額外在Idea編譯器里面配置Groovy環(huán)境。

如圖所示

創(chuàng)建項目時選擇Groovy選項,可以不用勾選Kotlin環(huán)境直接創(chuàng)建,畢竟要看如何從Java到Groovy。這里分別舉幾個比較常用的例子。

3.1 對應(yīng)第一個項目

class HelloGroovy {
    static void main(String[] args) {
        System.out.println("hello Groovy!");
    }
}

這是很標(biāo)準(zhǔn)的第一項java項目。接下來我們看看 Groovy 的第一個項目

def test() {
    "hello Groovy!" //方法返回值不用寫return,已最后一句話代碼作為方法的返回類型
}

println(test()) //代碼末尾可以省略 分號

println test() //打印甚至還能省略外面的一對大括號。

接下來看看我們經(jīng)常用的循環(huán):

3.2 對應(yīng)的循環(huán)

class HelloGroovy {
    static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            System.out.print(i+"\t ha")
        }
//        System.out.println("hello Groovy!")
    }
}

這里不用多說了,java大家都熟悉?,F(xiàn)在看看Groovy的語法。

3.times {
    println it+"\t haha"
}

或者

(0..2).forEach{
    println it+"\t haha"
}

運行效果

0    haha
1    haha
2    haha

熟悉Kotlin的小伙伴應(yīng)該能夠秒懂這段代碼,畢竟 kotlin 是在 groovy基礎(chǔ)上進階改良的,所以作為 Kotlin的前輩,語法幾乎都是類似的。

3.3 對應(yīng)的安全操作符

我們就以最經(jīng)典的非空判斷為準(zhǔn)。

class HelloGroovy {

    static String toUpperCase(String content) {
        if (content == null || content.length() == 0) {
             return "null";
        }
        content = content.toUpperCase();
        return content;
    }

    static void main(String[] args) {
        String content = "abc";
        System.out.println(toUpperCase(content));
    }

}

這里很經(jīng)典的非空判斷,不為空就轉(zhuǎn)大寫。接下來看看Groovy對應(yīng)的

def toUpperCase(str) {
    str?.toUpperCase()
}

println toUpperCase("abc")
println toUpperCase(null)

Groovy運行效果

ABC
null

學(xué)過Kotlin的小伙伴都知道,Kotlin代碼自帶非空檢測,只要可能為空的部分就必須讓開發(fā)者處理,否則連編譯都不能通過。要想通過編譯,要么處理為永不為空,要么調(diào)用前加一個問號,表示為空就不執(zhí)行。這里的 Groovy 語法和Kotlin 一樣。

3.4 數(shù)據(jù)類型

在開發(fā)中我們定義對應(yīng)的變量,肯定離不開對應(yīng)的數(shù)據(jù)類型。在我們熟悉的Java中,我們所使用的基本數(shù)據(jù)類型都會有裝箱拆箱的操作,比如說。

  • 基本數(shù)據(jù)類型

    byte、short、int、long、float、double、char、boolean

  • 包裝類(裝箱、拆箱)

    String、Byte、Short、Integer、Long、Float、Double、Char、Boolean

而在Groovy中,因為它具有動態(tài)類的特性,所以它從一開始就支持自動裝箱。實際上,必要時Groovy會自動將基本類型視作對象。

3.5 字符串

Java大家都再熟悉不過了,后面就直接開始貼Groovy的代碼。

def name = 'carName'
def realName = "$name:AAAA"
println name.getClass()
println realName.getClass()
def string='''
carName
is
$name
'''
println string

運行效果

class java.lang.String
class org.codehaus.groovy.runtime.GStringImpl

carName
is
$name

Process finished with exit code 0

從這里可以看出:

  • 單引號字符串是java.lang.String類型,同時不支持插值
  • 雙引號字符串在沒有使用插值表達式情況下是java.lang.String類型, 但如果有插值表達式使用的話,就是groovy.lang.GString類型
  • 三引號字符串表示多行的字符串。不必將字符串分割成幾塊,也不必用連接符或換行符轉(zhuǎn)義字符來將字符串跨行

3.6 數(shù)組和列表

def array = ["1", "2", 3]
println array.getClass()
// int []
String[] array2 = ["1",new Object(),2, "3"]
//def array2 = [1, 2, 3] as int[]
println array2.getClass()

println array2[1].toString()
println array2[1].getClass()

可以看出,這里定義了一個集合和一個數(shù)組,在集合和數(shù)組里面,我故意放入了不同類型的數(shù)據(jù),代碼也沒有報錯,我們運行看看效果。

class java.util.ArrayList
class [Ljava.lang.String;
java.lang.Object@3b4ef7
class java.lang.String

由此我們可得:

  • 數(shù)組和列表都是使用逗號分割列表的值,使用方括號括起來表示
  • Groovy中的數(shù)組和列可以隨意轉(zhuǎn)換
  • def定義的變量會自動推斷 [ ] 類型是列表
  • Groovy列表是普通的JDK java.util.List,因為Groovy中沒有定義自己的集合類

3.7 范圍

范圍是一種特殊的列表,由序列中的第一個和最后一個值表示,Range可以是包含或排除。包含范圍包括從第一個到最后一個的所有值,而獨占范圍包括除最后一個之外的所有值。

(0..2).forEach{
    println it+"\t haha"
}
('a'..<'d').forEach{
    println it
}

def range = 0..10
println range.getClass()

運行效果

0    haha
1    haha
2    haha
a
b
c
class groovy.lang.IntRange
Process finished with exit code 0

由此我們可得:

  • 1..10 包含范圍的示例
  • 1..<10 獨占范圍的示例 (開區(qū)間)

3.8 映射

映射(也稱為關(guān)聯(lián)數(shù)組,字典,表和散列)是對象引用的無序集合。Map集合中的元素由鍵值訪問。Map中使用的鍵可以是任何類,如果不能推斷具體key類型,默認(rèn)就是字符串。

在Groovy中可以使用特定的表述方式來指定映射

// [k1:v1,k2:v2]
def map = [a: 11, b: 12]
map.forEach { k, v ->
    println "key=${k.class} , value=$v"
}

def value = map['a']
println value

運行效果

key=class java.lang.String , value=11
key=class java.lang.String , value=12
11

由此我們可得:[k1:v1,k2:v2] 具有鍵值對的集合。

最后

您的點贊收藏就是對我最大的鼓勵! 歡迎關(guān)注我,分享Android干貨,交流Android技術(shù)。 對文章有何見解,或者有何技術(shù)問題,歡迎在評論區(qū)一起留言討論!最后給大家分享一些Android相關(guān)的視頻教程,感興趣的朋友可以去看看。

本文轉(zhuǎn)自 https://juejin.cn/post/7020709822630723621,如有侵權(quán),請聯(lián)系刪除。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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