本文出自博客Vander丶CSDN博客,如需轉載請標明出處,尊重原創謝謝
博客地址:http://blog.csdn.net/l540675759/article/details/69228418
寫作目的
1.在Android Studio上不可避免的會涉及到Gradle的構建,而Gradle的構建正是基於Groovy之上.
2.相當於Groovy語法上的總結記錄的博客,後續會繼續更新.
3.更好的總結,有利於知識的鞏固.
簡介
Groovy是從Java衍生出來的,並且運行在Java虛擬機上的語言.其目標是不管作爲腳本語言,還是編程語言,都可以簡單、直接使用。
Groovy的一些基本語法
打印字符串到屏幕上
println 'Hello ,World'
println "Hello ,World"
在Groovy中,字符串可以被單引號或者雙引號包裹,都可以表達出字符串的含義。
但是他們有不同的用途,雙引號字符串可以插入表達式,也就是可以插入佔位符,這些佔位符可以是變量也可以是方法,包含一個單獨變量的佔位符表達式可以只含有“$”前綴。
//def 是Groovy中聲明變量的關鍵字
def name = 'Andy'
//在這裏將佔位符替換成name變量
def getting = "Hello , ${name}"
//在這裏是將佔位符替換成 方法結果
def name_size = "Your name is ${name.size()} characters long."
類和成員變量
在Groovy中創建一個類和在Java中創建一個類相似.
//請注意:無論是類,還是成員變量,包括方法都沒有明確的訪問修飾符.
//Groovy中的默認訪問修飾符與Java不同.
//類和方法一樣,是公有的,而類的成員確實私有的.
class MyGroovyClass {
String greeting
void setGreeting(String greeting) {
this.greeting = greeting
}
String getGreeting() {
return greeting
}
}
使用一個類,包括使用一個類的成員變量:
//使用def關鍵字來創建新的變量,創建類也是
def instance =new MyGroovyClass()
instance.setGreeting('Hello World')
//當你試圖直接調用一個成員變量時,實際上,你調用的是Getter方法,這裏還可以用更簡短的方式表達
instance.getGreeting()
instance.getGreeting
方法
Groovy中的方法就像使用變量一樣,你無須爲你的方法定義一個特定的返回類型,但如果爲了方法能夠更清新,也可以指定返回對象,在Groovy中,方法的最後一行通常默認返回,即使沒有return關鍵字。
def square(def num){
num * num
}
square 4
在Groovy的方法中,無論是返回類型,還是參數類型都沒有明確的定義。這裏使用了def關鍵字,而不是一個明確的類型,而且在沒有使用return關鍵字的情況下,方法也隱晦的返回了一個值。
Closures
Closures是匿名代碼塊,可以接受參數和返回值。它們可以被視爲變量,被當做參數傳遞給方法。
閉包,是一種數據類型,它代表了一段可執行的代碼。其外形如下:
def aClosure = {//閉包是一段代碼,所以需要用花括號括起來..
String param1, int param2 -> //這個箭頭很關鍵。箭頭前面是參數定義,箭頭後面是代碼
println"this is code" //這是代碼,最後一句是返回值,
//也可以使用return,和Groovy中普通函數一樣
}
簡而言之,Closure的定義格式是:
def xxx = {paramters -> code} //或者
def xxx = {無參數,純code} //這種情況下是不需要->符號
Closure的調用和方法
aClosure.call("this is string",100) 或者
aClosure("this is string", 100)
如果沒有明確給closure指定一個參數,則Groovy會自動添加一個。這個參數通常被稱爲it,你可以在所有的closures中使用它,如果調用者沒有指定任何參數,則it爲空。
集合
在Gradle中使用Groovy時,有兩個重要的集合類型:lists和maps
在Groovy中創建一個新的list非常簡單,無須初始化:
List list = [1,2,3,4,5]
迭代List:
list.each(){
println it
}
另一個集合類型Map,在Gradle中非常重要,它可在多個Gradle設置和方法中使用。
Map pizzaPrices = [margheria:10,prpperoni:12]
並且可以使用get方法來獲取map中的特定項目:
pizzaPrices.get('pepperoni')
pizzaPrices['pepperoni']
而且Gradle也針對get方法做了簡寫
pizzaPrices.pepperoni
任務入門
定義任務
任務屬於一個Project對象,並且每個任務都可以執行task接口。定義一個新任務的最簡單方式是,執行將任務名稱作爲其參數的任務方法:
task hello
其創建了任務,但當你執行時,它不會做任何事情。爲了創建一個有用的任務,你需要添加一些動作。初學者通常會犯的一個錯誤是像下面這樣創建任務:
task hello{
println 'Hello , world!'
}
當你執行該任務時,會看到輸出如下:
$ gradlew hello
Hello , world!
:hello
從輸出來看,你可能覺得該任務運行了,但實際上,“Hello , world!”在執行該任務之前就已經被打印出來了。
原因就是,在任意Gradle構建中,都有三個階段:初始化階段、配置階段和執行階段。而上述的任務則是設置了任務的配置。
如果你想在執行階段給一個任務添加動作,則應該使用下面的表示法:
task hello << {
println 'Hello , world'
}
唯一的不同就是closure之前的<<,其告知Gradle,代碼在執行階段執行,而不是在配置階段。
Task在Gradle中有很多簡寫,在Gradle中定義任務的常用方式有以下幾種:
task(hello) << {
println 'Hello , world!'
}
task('hello') << {
println 'Hello ,world!'
}
tasks.create(name: 'hello') << {
println 'Hello , world!'
}
任務剖析
Task接口是所有任務的基礎,其定義了一系列屬性和方法。所有這些都是由一個叫做DefaultTask的類實現的。這是標準的任務實現方式,你創建的每一個新的任務,都是基於DefaultTask的。
每個任務都包含一個Action對象的集合。當一個任務被執行時,所有這些動作會以連續的順序被執行。你可以使用doFirst()和doLast()方法來爲一個任務添加動作。這些方法都是以一個closure作爲參數,然後被包裝到一個Action對象中的。
task hello {
println 'Configuration'
doLast {
println 'Goodbye'
}
doFirst{
println 'hello'
}
}
當執行hello task時輸出如下:
$ gradlew hello
Configuration
:hello
hello
Goodbye
即使打印“Goodbye”的代碼在“Hello”的代碼之前定義,但當執行task時,他們仍會按正確的順序執行。你甚至可以多次使用doFirst()和doLast(),如下所示:
task mindTheOrder{
doFirst{
println 'Not really first'
}
doFirst{
println 'First!'
}
doLast{
println 'Not really last'
}
doLast{
println 'Last!'
}
}
執行這個task的輸出如下:
$ gradlew mindTheOrder
:mindTheOrder
First!
Not really first.
Not really last.
Last!
注意,doFirst()總是添加一個動作到task的最前面,而doLast()總是添加一個動作到最後面,這意味着,當使用這些方法的時候,順序很重要。
當涉及給tasks排序時,可以使用mustRunAfter方法.
當使用mustRunAfter()時,你需要指定,如果兩個任務都被執行,那麼必須有一個任務始終先執行。
task task1 <<{
println 'task1'
}
task task2 <<{
println 'task2'
}
task2.mustRunAfter task1
同時運行task1和task2,不管你指定了什麼樣的順序,task1總是在task2之前執行。
gradlew task2 task1
:task1
task1
:task2
task2
在這兩個任務之間,mustRunAfter()方法不會添加任何依賴,因而我們可以只執行task2而不執行task1。如果你需要一個任務依賴於另一個,那麼可使用dependsOn()方法。
dependsOn()的例子
task task1 << {
println 'task1'
}
task task2 << {
println 'task2'
}
task2.dependsOn task1
當你試圖只執行task2而不執行task1時,結果如下:
$ gradlew task2
:task1
task1
:task2
task2
使用mustRunAfter(),當同時執行task1和task2時,task1總是在task2之前執行,兩者也可以獨立執行。使用dependsOn(),即使在未明確提及的情況下,task2的執行也總是會觸發task1.這是一個重要的區別。
參考
1.Gradle for Android 中文版
2.深入理解Android(一):Gradle詳解
http://www.infoq.com/cn/articles/android-in-depth-gradle