一、Gradle 的基本理解
Gradle 是一種基于Groovy的動(dòng)態(tài)DSL,而Groovy語言是基于jvm的動(dòng)態(tài)語言醉锄。
很多小伙伴看了上面的定義覺得是一臉的懵逼,這等于沒有講浙值。我還是不懂恳不,什么是DSL, 什么是基于jvm的動(dòng)態(tài)語言开呐。
下面我講為大家一一解釋烟勋,爭取用最簡單的方式讓大家理解的更透徹。
首先:什么是DSL负蚊,DSL 因?yàn)槿Q:Domain-Specific Language 神妹。中文:領(lǐng)域特定語言,如何去理解這個(gè)領(lǐng)域特定語言呢家妆,簡單理解就是在某個(gè)特定的領(lǐng)域去使用的語言鸵荠。如:HTML,用于網(wǎng)頁的編寫
第二什么是基于jvm的動(dòng)態(tài)語言:這里我們很快的能聯(lián)想到j(luò)ava伤极。java也是基于jvm的蛹找,但是java是靜態(tài)類型語言姨伤。所以我們只需要區(qū)分:動(dòng)態(tài)類型語言的關(guān)鍵特征是它的類型檢查的主體過程是在運(yùn)行期而不是編譯期
二、Gradle 中兩大重要概念
一個(gè)是Project庸疾,另一個(gè)則是 Task乍楚。后面我們會(huì)結(jié)合android 項(xiàng)目來講,這兩個(gè)重要的部分届慈。
1徒溪、理解 Project
構(gòu)建項(xiàng)目至少要有一個(gè),或者多個(gè)Project 去完成金顿,如何去理解這句話的意思了臊泌。首先,我們需要知道的是項(xiàng)目的構(gòu)建是通過gradle 去完成揍拆。gradle去幫我們完成在app構(gòu)建過程中需要完成的事情渠概,如:需要將資源文件通過aapt,轉(zhuǎn)換成 R文件嫂拴,和app sourceCode ,然后通過javac 去將java文件轉(zhuǎn)化成class文件播揪,最后將文件轉(zhuǎn)化成dex文件等。這里不明白的需要去看一下我寫的另外一篇文章APK文件構(gòu)建流程筒狠。
簡單理解:在android 中每一個(gè)build.gradle 就對(duì)應(yīng)這一個(gè)Project猪狈。如下我創(chuàng)建了一個(gè)項(xiàng)目,項(xiàng)目中有兩個(gè)build.gradle 所以就有兩個(gè)Project辩恼。
補(bǔ)充一下:你知道圖中 1 和 2 誰先執(zhí)行嗎 ?运挫,這里我在每個(gè)build.gradle 中對(duì)應(yīng)的去輸出状共。如下:
由上圖,我們能清楚的看到谁帕,最外層的build.gradle 是最先執(zhí)行的峡继,而后是 app 中的build.gradle 。這里留一個(gè)問題匈挖,如果有多個(gè)model碾牌,會(huì)有多個(gè)build.gradle ,就意味著我們有多個(gè)project,那么這些project 的執(zhí)行先后順序又是怎么樣的儡循。
2舶吗、理解Task
Task 是基于Project 的,一個(gè)Project中可以包含多個(gè)Task择膝。每個(gè)Task 中包含了一系列的動(dòng)作(待執(zhí)行的代碼)誓琼。
總結(jié):項(xiàng)目再構(gòu)建的過程中,首先會(huì)集合所有Project 和Task.然后按照順序去執(zhí)行每一個(gè)動(dòng)作,就是每一段代碼腹侣。就像java中代碼執(zhí)行一樣叔收。
三、構(gòu)建的生命周期
上面已經(jīng)基本提及了生命周期傲隶,這里系統(tǒng)的講一下饺律。
1、項(xiàng)目初始化:根據(jù)有多少個(gè)build.gradle 去創(chuàng)建 project跺株。所以這個(gè)階段就是Project的創(chuàng)建階段复濒。
2、配置階段:執(zhí)行build.gradle乒省。為對(duì)應(yīng)的Project 創(chuàng)建和配置Task芝薇。所以這個(gè)階段是Task的創(chuàng)建和配置階段
3、執(zhí)行階段:gradle會(huì)去決定執(zhí)行那個(gè)tasks.哪一個(gè)tasks會(huì)被執(zhí)行完全依賴開始構(gòu)建時(shí)傳入的參數(shù)和當(dāng)前所在的文件夾位置有關(guān)
四作儿、理解 build.gradle 的配置文件
注意:基于gradle構(gòu)建的項(xiàng)目,至少有一個(gè)build.gradle馋劈,所有我們先來看
1攻锰、android 項(xiàng)目最外層的 build.gradle
buildscript :定義了全局的相關(guān)屬性
repositories:定義了倉庫,一個(gè)倉庫代表著你的依賴包的來源
dependencies:用來定義構(gòu)建過程妓雾。這意味著你不應(yīng)該在該方法體內(nèi)定義子模塊的依賴包娶吞,你僅僅需要定義默認(rèn)的Android插件就可以了,因?yàn)樵摬寮梢宰屇銏?zhí)行相關(guān)Android的tasks
allprojects:方法可以用來定義各個(gè)模塊的默認(rèn)屬性械姻,你可以不僅僅局限于默認(rèn)的配置妒蛇,未來你可以自己創(chuàng)造tasks在allprojects方法體內(nèi),這些tasks將會(huì)在所有模塊中可見楷拳。
其中:repositories { } 這個(gè)叫閉包绣夺,還有 dependencies { } 等 類似于? ?a { } 這樣的結(jié)構(gòu)
啥叫閉包這個(gè)給大家解釋一下
2、閉包:
一個(gè)代碼塊欢揖,理解成一個(gè)匿名函數(shù)陶耍。在外面調(diào)用的時(shí)候,可以將它作為方法的實(shí)參傳遞給方法的形參她混,并在方法中調(diào)用這個(gè)匿名函數(shù)烈钞。此代碼塊或者匿名函數(shù)可以復(fù)制給一個(gè)變量,時(shí)期具有自執(zhí)行的能力坤按。且最后一行執(zhí)行的語句作為匿名函數(shù)的返回毯欣。、
解釋如下:可以將它作為方法的實(shí)參傳遞給方法的形參:意思是這個(gè)方法臭脓,可以是個(gè)參數(shù)酗钞,傳給一個(gè)方法。如下:
我在build.gradle 中創(chuàng)建了一個(gè)task? 這個(gè)task叫test ,在test 中,我創(chuàng)建了一個(gè)閉包 { } 并把這個(gè)閉包給了t算吩。 這樣t 就可以通過 .call()的方式調(diào)用這個(gè)匿名函數(shù)留凭。最后在控制臺(tái)輸出 test
3、模塊內(nèi)的 build.gradle
從上面看偎巢,總體分為三個(gè)部分蔼夜。1.、plugin 閉包压昼,2求冷、android 閉包 3、dependencies 閉包窍霞,接下來分別來講一下每個(gè)閉包的作用匠题,以及具體含義。
1但金、插件韭山,在plugin中定義的是android 應(yīng)用的插件,其是google的Android開發(fā)團(tuán)隊(duì)編寫的插件冷溃,能夠提供所有關(guān)于Android應(yīng)用和依賴庫的構(gòu)建钱磅,打包和測試。
'com.android.application'似枕,表示該模塊為應(yīng)用程序模塊盖淡,可以直接運(yùn)行,打包得到的是.apk文件
'com.android.library'(老)'java-library'(新)凿歼,表示該模塊為庫模塊褪迟,只能作為代碼庫依附于別的應(yīng)用程序模塊來運(yùn)行,打包得到的是.aar文件
2答憔、android 的屬性
在buildTypes 中還有很多其他配置的屬性味赃,因?yàn)檫@些屬性不是我們想講的重點(diǎn),所以這里就不一一介紹了虐拓,有興趣的小伙伴可以去了解一下
3洁桌、依賴包
依賴模塊作為gradle默認(rèn)的屬性之一(這也是為什么其放在了Android的外面),為你的app定義了所有的依賴包侯嘀。
總結(jié)
前面我們簡單的講了一下gradle的基本理解另凌,以及兩大重要概念,以及gradle的構(gòu)建生命周期戒幔。后面又結(jié)合android 去了解了一下build.gradle的組成吠谢,以及基本屬性,同時(shí)擴(kuò)展的講解了閉包的概念诗茎。后面我們會(huì)重點(diǎn)講解gradle 的project 工坊、tasks献汗、gradle的插件開發(fā)內(nèi)容,帶大家一步一步的走進(jìn)gradle并深入的了解gradle.