Gradle對於咱們大多數Android開發者能夠說是熟悉又陌生。但這個理由並不足以讓我有動力寫下這篇文章,其主要由於是這樣的:最近參與項目開發,發現項目工程裏的的build.gradle比以前接觸的的複雜了許多,雖然大部份內容經過表面英文也勉強能看懂,但仍是有些內容會讓人懵逼。尤爲是gradle出錯的時候,我第一時間會運用一個很是熟練的技能,ctrl+c問題,ctrl+v到google,而後經過google出來的結果跟着改,運氣不錯喲,這麼簡單的改動就gradle經過了,這時喜悅以前噴涌而出,嘴角開始瘋狂的上揚。但其實心裏是很虛的,由於你根本不知道是基於什麼原理去解決的。因此總的來講本篇博客的目的就是兩個:html
本篇博客的核心內容分三點:java
在學習gradle的過程當中最好記住下面一句話,避免在gradle的摩天大樓中迷失了方向android
Gradle腳本是基於Groovy語音的,於是它必定要遵循Groovy的語法git
Groovy是一門腳本語言,也是一門JVM語言,它最終是要編譯成class文件而後在jvm上執行,因此Java語言的特性Groovy都支持,咱們徹底能夠混寫Java和Groovy。咦,怎麼這段話好像在介紹kotlin見過呀!是的,若是你學過kotlin你會發現,kotlin和groovy的不少語法規則都同樣。github
既然如此,那Groovy的優點是什麼呢?簡單來講:Groovy提供了更加靈活簡單的語法,大量的語法糖以及閉包特性可讓你用更少的代碼來實現和Java一樣的功能。好比解析xml文件,Groovy就很是方便,只須要幾行代碼就能搞定,用Java則須要幾十行代碼。api
下面只簡單的介紹Groovy的幾個語法,更多的語法能夠參考官方文檔,本文的重點再也不這裏。bash
def name = "world"
println "Hi ${name}"
複製代碼
def a = 1 //省略了分號
def b = "hello world"
def int c = 1
def hello(msg) { //參數類型可省略
println (msg)
1 //方法返回值可省略return
}
複製代碼
簡單的理解,經過一對{}把代碼塊框起來,做爲一個總體對象來處理數據結構
{
[closureParameters ->]
sataments
}
複製代碼
[]內容是能夠省略的,但不表明沒有,Groovy自動幫我嗎分析推斷,從而省去人工書寫的繁瑣過程閉包
舉幾個栗子jvm
{ -> item++ } //引用一個變量item
{ it -> println it } //使用隱含閉包參數it
{ println it } //省略隱含閉包參數it
{ name -> println name } //顯示閉包參數
{ string x, int y -> //多個閉包參數
printIn "hey ${x} the value is $(y}" } 複製代碼
Groovy中的很多運算符會被映射爲針對對象的常規函數調用。譬如:
a + b 會被Groovy 解釋爲 a.plus (b)
a - b 會被Groovy解釋爲 a.minus(b)
a[b] = c 會被Groovy解釋爲 a.putAt(b, c)
複製代碼
正由於有了這樣的特性,纔有了咱們常見的task語句:
task helloworId <<
{
println 'hello, world } 複製代碼
gradle完成它的自動化編譯使命,須要通過三個過程,也就是它的生命週期
初始化的階段主要職責是定位有哪些須要處理的build文件。若是是單個工程,就會識別出單獨的build文件做爲下一個階段的輸入。若是是多工程,就會找到多個build文件,把它們做爲下一階段的輸入。這個階段settings.gradle文件會被解析。
處理全部的模塊的build腳本,處理依賴,屬性等。對於Android來講每一個模塊的build.gradle文件會被解析並配置,這個時候會構建整個task的鏈表(僅僅指存在依賴關係的task的集合,不是數據結構的鏈表)。這一階段的目標產物其實是由一個個task組成的DAG圖(Directed Acyclic Graph)
這個階段是真正體現Gradle價值的一個階段,他會根據上一階段的DAG結果來執行某一個特定的task,這個task所依賴的其餘task都將會被提早執行
下面有一個栗子能夠直觀的感覺到這個週期過程,傳送門:
Task能夠理解爲Gradle的執行單元。Gradle就是經過一個個task來完成具體的構建任務,下面咱們就來看看Task的定義。
task myTask {
println "config myTask"
}
複製代碼
執行task: gradle myTask 或者 gradle clean
config myTask
能夠看出,只要我執行任何一個task,都會輸出config myTask。這是爲何呢?
由於每一個task執行以前都須要進行一遍完整的配置。
但不少時候咱們都不須要寫配置代碼,那還這麼作不是很影響執行速度?
這個時候能夠經過gradle的提供的一些API方法:
那麼把配置代碼和執行代碼分開來能夠寫成這樣:
task myTask {
println "config myTask"
}
myTask << {
println "after execute myTask"
}
myTask.doFirst {
println "before execute myTask"
}
複製代碼
固然。不少時候在定義task的時候能夠繼承Gradle自己提供的Task,好比Copy、Delete、Sync等。
舉個栗子,繼承Delete的task
task clean(type: Delete) {
delete rootProject.buildDir
}
複製代碼
用於刪除整個project根目錄下的build文件夾
筆者分享的這篇內容並非要讓你掌握Gradle的某個具體知識點,畢竟Gradle的水仍是很深的,
要想深刻的學習Gradle,仍是要須要看官方文檔的