筆記來(lái)源于以下文章
1. http://liuwangshu.cn/application/gradle/1-study-gradle.html
2. https://blog.csdn.net/singwhatiwanna/article/details/76084580
1. 為什么是Gradle
Gradle是目前Android主流的構(gòu)建工具献丑,不管你是通過(guò)命令行還是通過(guò)AndroidStudio來(lái)build,最終都是通過(guò)Gradle來(lái)實(shí)現(xiàn)的纹冤,所以學(xué)習(xí)Gradle非常重要庄拇。
目前國(guó)內(nèi)對(duì)Android領(lǐng)域的探索已經(jīng)越來(lái)越深醉鳖,不少技術(shù)領(lǐng)域如插件化旋恼、熱修復(fù)昼牛、組件化泛鸟、構(gòu)建系統(tǒng)等都對(duì)Gradle有迫切的需求蝠咆,不懂Gradle將無(wú)法完成上述事情,所以Gradle必須要學(xué)習(xí)北滥。
2. 項(xiàng)目自動(dòng)化
Gradle是一個(gè)構(gòu)建工具刚操,為什么要用構(gòu)建工具,這里就需要先從項(xiàng)目自動(dòng)化開(kāi)始講起再芋。
在我們開(kāi)發(fā)軟件時(shí)菊霜,會(huì)面臨相似的情況就是,我們需要去用IDE來(lái)進(jìn)行編碼济赎,當(dāng)完成一些功能時(shí)會(huì)進(jìn)行編譯鉴逞、單元測(cè)試、打包等工作联喘,這些工作都需要開(kāi)發(fā)人員手動(dòng)來(lái)實(shí)現(xiàn)华蜒。而一般的軟件都是迭代式開(kāi)發(fā)的,一個(gè)版本接著一本版本豁遭,每個(gè)版本又可能有很多的功能叭喜,如果開(kāi)發(fā)每次實(shí)現(xiàn)功能時(shí)都需要手動(dòng)的進(jìn)行編譯、單元測(cè)試和打包等工作蓖谢,那顯然會(huì)非常耗時(shí)而且也容易出現(xiàn)問(wèn)題捂蕴,因此項(xiàng)目自動(dòng)化應(yīng)運(yùn)而生,它有以下優(yōu)點(diǎn):
- 它可以盡量防止開(kāi)發(fā)手動(dòng)介入從而節(jié)省了開(kāi)發(fā)的時(shí)間并減少錯(cuò)誤的發(fā)生闪幽。
- 自動(dòng)化可以自定義有序的步驟來(lái)完成代碼的編譯啥辨、測(cè)試和打包等工作。
- IDE可能受到不同操作系統(tǒng)的限制盯腌,而自動(dòng)化構(gòu)建是不會(huì)依賴(lài)于特定的操作系統(tǒng)和IDE的溉知,具有平臺(tái)無(wú)關(guān)性。
3. 構(gòu)建工具
構(gòu)建工具用于實(shí)現(xiàn)項(xiàng)目自動(dòng)化腕够,是一種可編程的工具级乍,你可以用代碼來(lái)控制流程,最終生成可交付的軟件帚湘。構(gòu)建工具可以幫助你創(chuàng)建一個(gè)重復(fù)的玫荣、可靠地、無(wú)需手動(dòng)介入的大诸、不依賴(lài)于特定操作系統(tǒng)和IDE的構(gòu)建捅厂。下面拿APK的構(gòu)建過(guò)程來(lái)舉例贯卦。
3.1 APK的構(gòu)建過(guò)程
APK的構(gòu)建過(guò)程可根據(jù)官方提供的流程圖如下圖所示
APK的構(gòu)建過(guò)程主要分為以下幾步:
- 通過(guò)AAPT(Android Asset Packaging Tool)打包res資源文件,比如AndroidManifest.xml焙贷、xml布局文件撵割,并將這些xml文件編譯為二進(jìn)制,其中assets和raw文件夾的文件不會(huì)被編譯為二進(jìn)制盈厘,最終會(huì)生成R.java和resource.arsc文件睁枕。
- AIDL工具會(huì)將所有的aidl接口轉(zhuǎn)化為對(duì)應(yīng)的Java接口。
- 所有的Java代碼沸手,包括R.java和Java接口都會(huì)被Java編譯器編譯成.class文件外遇。
- Dex工具會(huì)將上一步生成的.class文件、第三方庫(kù)和其他.class文件編譯成.dex文件契吉。
- 上一步編譯生成的.dex文件跳仿、編譯過(guò)的資源、無(wú)需編譯的資源(如圖片等)會(huì)被ApkBuilder工具打包成APK文件捐晶。
- 使用Debug Keystore或者Release Keystore對(duì)上一步生成的APK文件進(jìn)行簽名菲语。
- 如果是對(duì)APK正式簽名,還需要使用zipalign工具對(duì)APK進(jìn)行對(duì)齊操作惑灵,這樣應(yīng)用運(yùn)行時(shí)減少內(nèi)存的開(kāi)銷(xiāo)山上。
以上步驟可以看出,APK的構(gòu)架過(guò)程是比較繁瑣的英支,而且這個(gè)構(gòu)建過(guò)程又是時(shí)常重復(fù)的佩憾,如果沒(méi)有構(gòu)建工具,手動(dòng)去完成構(gòu)建工作干花,無(wú)疑對(duì)于開(kāi)發(fā)人員是個(gè)折磨妄帘。也會(huì)可能在過(guò)程中產(chǎn)生很多問(wèn)題,導(dǎo)致項(xiàng)目開(kāi)發(fā)周期變長(zhǎng)池凄。
在Gradle出現(xiàn)之前抡驼,有三個(gè)基于Java的構(gòu)建工具:Ant、Gant和Maven肿仑,他們被應(yīng)用于Java或者Android開(kāi)發(fā)中致盟,下面簡(jiǎn)單介紹一下:
2.2 Apache Ant
官網(wǎng):http://ant.apache.org/
Ant在這里不是螞蟻的意思(雖然它的圖標(biāo)是螞蟻),而是Another Neat Tool的意思尤慰。
它是由 James Duncan Davidson 開(kāi)發(fā)的(Tomcat 最初的開(kāi)發(fā)者)勾邦,最初是用來(lái)構(gòu)建 Tomcat。在2000年割择,Ant成為一個(gè)獨(dú)立的項(xiàng)目并被發(fā)布出來(lái)。Ant 是由 Java 編寫(xiě)的構(gòu)建工具萎河,它的核心代碼是由Java編寫(xiě)的荔泳,因此具有平臺(tái)無(wú)關(guān)性蕉饼,構(gòu)建腳本是XML格式的(默認(rèn)為bulid.xml),如果你熟悉XML玛歌,那么Ant 就比較容易上手昧港。
Ant構(gòu)建腳本的樣式如下所示。
build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="hello">
<echo message="running build.xml which is equivalent to build.gant"/>
<property file="build.properties"/>
<target name="init" description="init target" >
<echo message="Executing init target"/>
</target>
<target name="hello" depends="init" description="say hello target">
<echo message="${echo.msg}"/>
</target>
</project>
Ant的構(gòu)建腳本由三個(gè)基本元素組成:一個(gè)project(工程)支子、多個(gè)target(目標(biāo))和可用的task(任務(wù))创肥。
Apache Ant有以下缺點(diǎn):
- Ant無(wú)法獲取運(yùn)行時(shí)的信息。
- XML作為構(gòu)建腳本的語(yǔ)言值朋,如果構(gòu)建邏輯復(fù)雜叹侄,那么構(gòu)建腳本就會(huì)又長(zhǎng)又難以維護(hù)。
- Ant需要配合lvy(一種管理項(xiàng)目的依賴(lài)工具)昨登,否則Ant很難管理依賴(lài)趾代。
- Ant在如何組織項(xiàng)目結(jié)構(gòu)方面沒(méi)有給出任何知道,這導(dǎo)致Ant雖然靈活性高丰辣,但這樣的靈活導(dǎo)致每個(gè)構(gòu)建腳本都是唯一的而且很難被破解撒强。
3.3 Gant
官網(wǎng):https://gant.github.io/
[圖片上傳失敗...(image-fa2b53-1551348478092)]
Gant 是一個(gè)基于Ant 的構(gòu)建工具,它在Ant的基礎(chǔ)上用Groovy寫(xiě)的DSL(領(lǐng)域特定語(yǔ)言)笙什。如果用Ant 實(shí)現(xiàn)構(gòu)建飘哨,但是不喜歡用XML來(lái)編寫(xiě)構(gòu)建腳本或者現(xiàn)有的XML構(gòu)建腳本很難維護(hù)和管理,那么Gant 是一個(gè)不錯(cuò)的選擇琐凭。
Gant構(gòu)建文件的樣式如下所示芽隆。
build.gant
Ant.echo(message : 'running build.gant')
Ant.property(file : 'build.properties')
def antProperty = Ant.project.properties
target(init : 'init target') {
echo(message : 'Executing init target')
}
target(hello : 'say hello target') {
depends(init)
echo(message : antProperty.'echo.msg')
}
setDefaultTarget(hello)
這個(gè)build.gant等同于此前Ant的bulid.xml
3.4 Apache Maven
官網(wǎng):http://maven.apache.org/
Maven于2004年發(fā)布,它的目標(biāo)是改進(jìn)開(kāi)發(fā)人員在使用Ant時(shí)面臨的一些問(wèn)題淘正。Maven最初是為了簡(jiǎn)化Jakarta Turbine項(xiàng)目的構(gòu)建摆马,它經(jīng)歷了Maven到Maven3的發(fā)展,Maven作為后來(lái)者鸿吆, 繼承了Ant的項(xiàng)目構(gòu)建功能囤采, 同樣采用了XML作為構(gòu)建腳本的格式。Maven具有依賴(lài)管理和項(xiàng)目管理的功能惩淳,提供了中央倉(cāng)庫(kù)蕉毯,能幫助我們自動(dòng)下載庫(kù)文件。
Maven的構(gòu)建腳本樣式如下
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Maven相比Ant的優(yōu)點(diǎn):
- Ant是過(guò)程式的思犁,開(kāi)發(fā)者需要顯示的指定每個(gè)目標(biāo)代虾,以及完成該目標(biāo)鎖需要執(zhí)行的任務(wù)。每一個(gè)項(xiàng)目激蹲,開(kāi)發(fā)著都需要重新編寫(xiě)這一過(guò)程棉磨,這樣會(huì)產(chǎn)生大量的重復(fù)。Maven是聲明式的学辱,項(xiàng)目的構(gòu)建過(guò)程和過(guò)程中的各個(gè)階段都由插件實(shí)現(xiàn)乘瓤,開(kāi)發(fā)者只需要聲明項(xiàng)目的基本元素就可以了环形,這很大程度消除了重復(fù)。
- Ant本身是沒(méi)有依賴(lài)管理衙傀,需要配合Ivy來(lái)管理依賴(lài)抬吟,而Maven本身就提供了依賴(lài)管理。
- Maven 使用約定而不是配置统抬,它為工程提供了合理的默認(rèn)行為火本,項(xiàng)目會(huì)知道去哪個(gè)目錄尋找源代碼以及構(gòu)建運(yùn)行時(shí)有那些任務(wù)去執(zhí)行,如果你的項(xiàng)目遵從默認(rèn)值聪建,那么只需要寫(xiě)幾行XML配置腳本就可以了钙畔。而Ant是使用配置且沒(méi)有默認(rèn)行為的。
Maven的缺點(diǎn):
- Maven提供了默認(rèn)的結(jié)構(gòu)和生命周期妆偏,這些可能不適合你的項(xiàng)目刃鳄。
- 為Maven寫(xiě)定制的擴(kuò)展過(guò)于累贅。
- Maven的中央倉(cāng)庫(kù)比較混亂钱骂,當(dāng)無(wú)法從中央倉(cāng)庫(kù)中的帶需要的類(lèi)庫(kù)時(shí)叔锐,我們可以手工下載復(fù)制到本地倉(cāng)庫(kù)中,也是建立組織內(nèi)部的倉(cāng)庫(kù)服務(wù)器见秽。
- 國(guó)內(nèi)連接Maven的中央倉(cāng)庫(kù)比較慢愉烙,需要連接國(guó)內(nèi)的Maven鏡像倉(cāng)庫(kù)。
- Maven缺乏文檔解取,不便于使用和理解步责。
4. Gradle的特性
Gradle是一款基于JVM的專(zhuān)注于靈活性和性能的開(kāi)源構(gòu)建工具。
build.gradle
apply plugin:'java'
group='com.mycompany.app'
archivesBaseName='my-app'
version='1.0-SNAPSHOT'
repositories{
mavenCentral()
}
dependencies{
testCompile 'junit:4.11'
}
這個(gè)build.gradlet等同于此前Maven的pom.xml禀苦÷希可以看出Groovy編寫(xiě)構(gòu)建腳本代碼量更少,可讀性更強(qiáng)振乏。
下面列出Gradle與競(jìng)爭(zhēng)對(duì)手不同的特性蔗包。
4.1 輕松地可擴(kuò)展性
Gradle有非常良好的拓展性。如果想要在多個(gè)構(gòu)建或者項(xiàng)目中分享可重用代碼慧邮,Gradle的插件會(huì)幫助你實(shí)現(xiàn)调限。將Gradle插件應(yīng)用于你的項(xiàng)目中,它會(huì)在你的項(xiàng)目構(gòu)建過(guò)程中提供很多幫助:為你的添加項(xiàng)目的依賴(lài)的第三方庫(kù)误澳、為你的項(xiàng)目添加有用的默認(rèn)設(shè)置和約定(源代碼位置耻矮、單元測(cè)試代碼位置)。其中Android Gradle插件繼承Java Gradle插件忆谓,在本系列后續(xù)的文章會(huì)介紹插件的內(nèi)容裆装。
4.2 采用了Groovy
Ant和Maven的構(gòu)建腳本是由XML來(lái)編寫(xiě)的,如果XML邏輯復(fù)雜內(nèi)容太多就不容易維護(hù)。Gradle可以使用Groovy來(lái)實(shí)現(xiàn)構(gòu)建腳本哨免,Groovy是基于Jvm一種動(dòng)態(tài)語(yǔ)言勾扭,它的語(yǔ)法和Java非常相似并兼容Java,因此你無(wú)需擔(dān)心學(xué)習(xí)Groovy的成本铁瞒。Groovy在Java的基礎(chǔ)上增加了很多動(dòng)態(tài)類(lèi)型和靈活的特性,比起XML桅滋,Gradle更具有表達(dá)性和可讀性慧耍。
4.3 強(qiáng)大的依賴(lài)管理
Gradle提供了可配置的可依靠的依賴(lài)管理方案。一旦依賴(lài)的庫(kù)被下載并存儲(chǔ)到本地緩存中丐谋,我們的項(xiàng)目就可以使用了芍碧。依賴(lài)管理很好的實(shí)現(xiàn)了在不同的平臺(tái)和機(jī)器上產(chǎn)生相同的構(gòu)建結(jié)果。
4.4 靈活的約定
Gradle可以為構(gòu)建你的項(xiàng)目提供引導(dǎo)和默認(rèn)值号俐,如果你使用這種約定泌豆,你的Gradle構(gòu)建腳本不會(huì)有幾行。比起Ant吏饿,Gradle不僅僅提供了約定踪危,還可以讓你輕松的打破約定。
4.5 Gradle Wrapper
Gradle Wrapper是對(duì)Gradle的包裝猪落,它的作用是簡(jiǎn)化Gradle本身的下載贞远、安裝和構(gòu)建,比如它會(huì)在我們沒(méi)有安裝Gradle的情況下笨忌,去下載指定版本的Gradle并進(jìn)行構(gòu)建蓝仲。Gradle的版本很多,所以有可能出現(xiàn)版本兼容的問(wèn)題官疲,這時(shí)就需要Gradle Wrapper去統(tǒng)一Gradle的版本袱结,避免開(kāi)發(fā)團(tuán)隊(duì)因?yàn)镚radle版本不一致而產(chǎn)生問(wèn)題。
4.6 可以和其他構(gòu)建工具繼承
Gradle可以和Ant途凫、Maven和lvy進(jìn)行繼承垢夹,比如我們可以把Ant的構(gòu)建腳本導(dǎo)入到Gradle的構(gòu)建中。
4.7 底層API
Gradle顯然無(wú)法滿(mǎn)足所有企業(yè)級(jí)構(gòu)建的所有要求颖榜,但是可以通過(guò)Hook Gradle的生命周期棚饵,來(lái)監(jiān)控和配置構(gòu)建腳本。
4.8 社區(qū)的支持和推動(dòng)
Gradle是一個(gè)開(kāi)源的項(xiàng)目掩完,它遵循了Apache License2.0協(xié)議噪漾。Gradle的優(yōu)良特性吸引了很多開(kāi)發(fā)者并形成了Gradle社區(qū),很多開(kāi)源軟件開(kāi)發(fā)者為Gradle的核心代碼做出了分享且蓬。
5. 如何學(xué)習(xí)Gradle
大部分人對(duì)Gradle表示一臉懵逼欣硼,每當(dāng)遇到一個(gè)問(wèn)題的時(shí)候都需要從網(wǎng)上去查,這是一個(gè)誤區(qū)恶阴。
Gradle不單單是一個(gè)配置腳本诈胜,它的背后是幾門(mén)語(yǔ)言豹障,如果硬讓我說(shuō),我認(rèn)為是三門(mén)語(yǔ)言焦匈。
Groovy Language
Gradle DSL
Android DSL
DSL的全稱(chēng)是Domain Specific Language血公,即領(lǐng)域特定語(yǔ)言,或者直接翻譯成“特定領(lǐng)域的語(yǔ)言”缓熟,算了累魔,再直接點(diǎn),其實(shí)就是這個(gè)語(yǔ)言不通用够滑,只能用于特定的某個(gè)領(lǐng)域垦写,俗稱(chēng)“小語(yǔ)言”。因此DSL也是語(yǔ)言彰触。
在你不懂這三門(mén)語(yǔ)言的情況下梯投,你很難達(dá)到精通Gradle的程度。這個(gè)時(shí)候從網(wǎng)上搜索况毅,或者自己記憶的一些配置分蓖,其實(shí)對(duì)你來(lái)說(shuō)是很大的負(fù)擔(dān)。但是把它們當(dāng)做語(yǔ)言來(lái)學(xué)習(xí)俭茧,則不需要記憶這些配置咆疗,因?yàn)檎Z(yǔ)言都是有文檔的,我們只需要學(xué)語(yǔ)法然后查文檔即可母债,沒(méi)錯(cuò)午磁,這就是學(xué)習(xí)方法,這就是正道毡们。
6. 總結(jié)
本篇文章從項(xiàng)目自動(dòng)化開(kāi)始講起迅皇,介紹了常用的構(gòu)建工具:Ant、Gant和Maven衙熔,最后介紹了Gradle的特性登颓,這些特性和其他競(jìng)爭(zhēng)的構(gòu)建工具相比有著很大的優(yōu)勢(shì)和吸引力,這也是為什么我們現(xiàn)在要用Gradle的原因红氯。