一、Gradle是目前Android主流的構建工具、我們在做項目的時候、有很多的配置都會放在項目的build.gradle文件中進行。
如版本、信息、包名、一些第三方依賴、或者打包時用到的簽名、混淆文件信息等。android開發(fā)離不開gradle。我們經(jīng)常會不可避免的與gradle打交道。所以學習gradle是很有必要的事情。
Gradle 是一個配置腳本,它的背后是由Groovy Language、 Gradle DSL、 Android DSL幾門語言。其中dsl是指領域特定語言。只能用于特定的某個流域。今天我們先來學習Groovy。
Groovy是一門jvm語言。它最終會編譯成class文件在jvm上執(zhí)行。所以它與java類似。甚至可以與java進行混寫。groovy的優(yōu)勢在于它有大量自己的特性與語法。更加方便的讓我們以更少的代碼完成與java同樣的功能。
二、配置環(huán)境
1、配置java環(huán)境變量 新建用戶變量JAVA_HOME、這里注意不要加;與bin路徑:正確為 D:\AndroidStudio\jre\ 錯誤為 D:\AndroidStudio\jre\bin或者D:\AndroidStudio\jre\bin;
將JAVA_HOME 用戶變量設置到系統(tǒng)變量path中 %JAVA_HOME%
2、配置Gradle環(huán)境變量 新建用戶變量GRADLE_HOME C:\Users\lihaiyang.gradle\wrapper\dists\gradle-5.4.1-all\3221gyojl5jsh0helicew7rwx\gradle-5.4.1
將GRADLE_HOME用戶變量加到系統(tǒng)變量path中 C:\Users\lihaiyang.gradle\wrapper\dists\gradle-5.4.1-all\3221gyojl5jsh0helicew7rwx\gradle-5.4.1\bin 系統(tǒng)變量是bin目錄下 因為 此目錄下有gradle.bat 文件


3、驗證是否配置成功
打開控制臺 cmd 執(zhí)行 gradle命令 如圖下所示為成功

二、groovy語言基礎(與世界說句hello)
首先我們先來寫一個學習任何語言的第一步先寫個helloWorld出來
1、創(chuàng)建一個build.gradle 文件(注意。文件名改成xx.gradle是不行的) 書寫以下代碼,并執(zhí)行gradle helloworld
解釋一下。grdle 執(zhí)行的是task 我們創(chuàng)建了一個helloworld的task 并打印一個println 輸出hello world 函數(shù)
task(helloworld).doLast {
println "hello world"
}

恭喜各位。已經(jīng)成功入門,進入groovy的世界了。
三、變量
對于groovy來說 它也是一種強類型的語言但是,它不用像java一樣指定某個變量的類型,它會自己去推斷。定義變量的方法 def xx;
task(helloworld).doLast {
def one = 1
def tow = "hello"
def three = 0.00d
def four = 0.1f
def five = true
println one.class
println tow.class
println three.class
println four.class
println five.class
}

在這里可以看出 最后打印出來的都是java.lang包下的數(shù)據(jù)類型。這里可以看出 它其實和java 是共通的。這里注意我們語句后面的;是可以省略的哦
四、定義方法
def func() {
}
int func(String str) {
retunr 1
}
int funcFour(){
1
}
def funcTow(def str) {
}
def funcThree(str) {
}
def funcFive(){
return 1; //這里的return 不可以省略
println "1" //這里沒有打印 沒有執(zhí)行下去
println "2"
}
這里大家看到定義了幾個方法、其中有很多是可以省略的 比如 返回值 return 語句 省略 return 、方法值參數(shù)可以省略類型、等。使用方法與java 一致 直接調(diào)用就可以了 。
五、String類型的拼接
對于String類型的拼接在我們AndroidManifest.xml文件中最為常見。我們先看一段代碼

在圖片上的代碼中我們看到紅框部分中標記的 applicationid 為我們的報名。我們可以在gradle中定義不同的報名來適配我們 androidManifest文件中使用。這樣我們修改報名之后。只需要修改一個位置。不用到androidManifest文件中去全局替換了。以下為groovy書寫。定義了a 與b變量 在c變量中使用%{x}進行引用。我們看我們打印出來的返回值,已經(jīng)是拼接后的值了
def a = 1
def b = "hello"
def c = "a=${a}, b=$"
println c
outputs:
a=1, b=hello
六、閉包
groovy中有一個特殊的類型叫做閉包、作為一種數(shù)據(jù)類型存在??梢宰鰹橐粋€方法的參數(shù)與返回值。也可以作為一個變量而存在
{ parameters ->
code
}
def closure = { int a, String b ->
println "a=${a}, b=$, I am a closure!"
}
def test = { a, b ->
println "a=${a}, b=$, I am a closure!"
}
def ryg = { a, b ->
a + b
}
closure(100, "renyugang")
test.call(100, 200)
def c = ryg(100,200)
println c
a=100, b=renyugang, I am a closure!
a=100, b=200, I am a closure!
另外、如果閉包不指定參數(shù)、那么它有一個隱藏參數(shù)it
// 這里省略了閉包的參數(shù)類型
def test = {
println "find ${it}, I am a closure!"
}
test(100)
outputs:
find 100, I am a closure!
七、list 與map
如何定義list 與map
def emptyList = []
def emptyMap = [:]
以上相當于定義了兩個空的object 集合 第一個為list 第二個為map
def test = [100, "hello", true]
def test = ["id":1, "name":"renyugang", "isMale":true]
對于list來講 我們來看看怎么使用
def test = [100, "hello", true]
test[1] = "world" //將index 為1 的元素值替換為world
println test[0] //打印 index為0的元素
println test[1] //打印 index為1的元素
test << 200 // 添加一個值為200的元素
println test.size //打印list的大小
outputs:
100
world
4
以上代碼為使用。其中有一個部分 為<< 位操作符。這個操作符與java中的add函數(shù)是一樣的
http://www.groovy-lang.org/api.html groovy api文檔

從文檔中我們可以看到 其中我們看到有很多方法我們很熟悉,我們來使用以下
task(helloworld).doLast {
def text = [1,2,3,4,5]
println "textSize"+text.size()
text.add(6)
println "text中index為5"+text[5]
println "textSize"+text.size()
println "刪除index為1的元素并打印其值"+text.remove(1)
println "獲取index為0的元素"+text[0]
println "textSize"+text.size()
}
> Task :helloworld output
textSize5
text中index為56
textSize6
刪除index為1的元素并打印其值2
獲取index為0的元素1
textSize5
我們可以看到與我們java對應的方法沒有差別。想要遍歷怎么辦。猜一下
task(helloworld).doLast {
def text = [1,2,3,4,5]
for (def entry : text){
println entry
}
}
> Task :helloworld output
1
2
3
4
5
map操作
task(helloworld).doLast {
def text = ["one": 1, "two": 2, "three": 3, "four": 4, "five": 5]
text << ["six" : 6] //增加元素
test["one"] = 2 //設置 key為one 的值為2
test.one= 900 //設置 key為one 的值為900
def keySet = text.keySet()
for (def key : keySet){
println "${key}+${text[key]}"
}
}
對于集合的遍歷剛才我們已經(jīng)通過與java 相同的方式進行了演示,如果我們想通過groovy的方式改怎么做的
我們可以查看另外一個文檔http://docs.groovy-lang.org/latest/html/groovy-jdk/index-all.html

我們可以看到又一個each方法 他是使用閉包的方式進行遍歷的
但是很不幸的是 list的each方法點進去是下面這樣的

大爺?shù)臎]有示例方法不知道怎么用啊,我們再看看map吧

這個還好有示例方法我們來依葫蘆畫瓢
def text = ["one": 1, "two": 2, "three": 3, "four": 4, "five": 5]
text.each { key, value ->
println "${key}=${value}"
}
text.each { entry ->
println entry
}
output
one=1
two=2
three=3
four=4
five=5
one=1
two=2
three=3
four=4
five=5
我們可以看到,成功了。這里我們發(fā)現(xiàn)他有兩種使用方法,一種是 閉包是兩個 變量 key value 它對應的就是
我們map 中的key value 第二種方式 就是是一個 entry 我們知道 在java 的map 中 每個元素是用entry 保存的所以這樣也很符合java數(shù)據(jù)結(jié)構的設計,這里的entry 是可以省略的。上邊已經(jīng)說到 如果閉包中只有一個元素變量的話是可以省略的。大家可以試一下
好了map 搞定了。list咋辦。猜吧(其實文檔應該能找到)
def textTwo = [ 1, 2, 3, 4, 5]
textTwo.each{
println it
}
output
1
2
3
4
5
完美
八、io
groovy 相比于java io 方便很多。當然我們完全可以使用 groovy 支持的java的解析方式用來解析。這個就不演示了。大家可以試試。我們這次演示的是groovy 提供的閉包的方式進行。
1、文件讀取
我們查看文檔的話我們可以看到 支持file 讀取的 有 eachByte eachLine 等


以上是api 文檔中的一部分 但是還是沒有示例代碼。一萬句mmp,幸虧有萬能的翻譯

可以看到參數(shù) 說是 第一個參數(shù)是行 第二個是可選參數(shù) 為從1開始的行號。來吧繼續(xù)猜代碼怎么寫
我們再看看 這個方法是誰得

這么簡單得翻譯軟件也可以剩下了 。 這個方法是 class File的方法 ,繼續(xù)猜。java 咋拿File對象 這里咋拿
然后按照閉包的方式寫
來吧 groovy 不是號稱 自動推斷類型么
def file = new def(text1.txt);
然后 mmp 報錯,看來它還沒成神
然后試了下
def file = new File("text1.txt");
不報錯了
def file = new File("text1.txt");
file.eachLine{
println it
}
file.eachLine{ x,y ->
println "${x},${y}"
}
}
> Task :helloworld
1,這
2,里
3,一
4,次
5,成
6,功
xml解析,文檔http://docs.groovy-lang.org/docs/latest/html/api/
這里只做演示。在文檔中我也只查到了 java方式的方法。沒有找到groovy方式的。大家可以自己在文檔中找一找
<resources>
<declare-styleable name="CircleView">
<attr name="circle_color" format="color">#98ff02</attr>
<attr name="circle_size" format="integer">100</attr>
<attr name="circle_title" format="string">renyugang</attr>
</declare-styleable>
</resources>
def xml = new XmlParser().parse(new File("attrs.xml"))
// 訪問declare-styleable節(jié)點的name屬性
println xml['declare-styleable'].@name[0]
// 訪問declare-styleable的第三個子節(jié)點的內(nèi)容
println xml['declare-styleable'].attr[2].text()
outputs:
CircleView
renyugang
Groovy 出了以上新特性以外還有其他的新特性
比如。默認的get set方法。groovy 中定義一個class 他的屬性是默認存在get set方法的、或者所有的Class 類型參數(shù) 都可以省略.class
def func(Class class){
}
func(File.class)
func(File)
1、with操作符
Book bk = new Book()
bk.id = 1
bk.name = "android art"
bk.press = "china press"
可以簡寫為:
Book bk = new Book()
bk.with {
id = 1
name = "android art"
press = "china press"
}
2、判斷是否為真
//java
if (name != null && name.length > 0) {}
可以替換為:
if (name) {}
3、簡潔的三元表達式
def result = name != null ? name : "Unknown"
// 省略了name
def result = name ?: "Unknown"
4、簡潔的非空判斷
if (order != null) {
if (order.getCustomer() != null) {
if (order.getCustomer().getAddress() != null) {
System.out.println(order.getCustomer().getAddress());
}
}
}
可以簡寫為:
println order?.customer?.address
使用斷言
在Groovy中,可以使用assert來設置斷言,當斷言的條件為false時,程序?qū)伋霎惓?因為我們使用Groovy是用來寫插件的。出錯了直接拋。讓使用插件的改 我們沒必要捕獲處理異常信息的。所以對異常處理不涉獵。
def check(String name) {
assert name
assert name?.size() > 3
}
1、對于switch 語句來講。groovy 支持更豐富的條件語句
def x = "haha"
def result = ""
switch (x) {
case String:result = "string" //String
break
case "foo": //字符串
result = "found foo"
case "bar": //因為上邊沒有break 這里的判斷允許失效。會執(zhí)行下一個語句
result += "bar"
break
case [4, 5, 6, 'inList']: result = "list" //list
break
case { it > 3 }: result = "number > 3" //判斷語句
break
case 12..30: result = "range" //范圍
break
case Integer: result = "integer" //基本數(shù)據(jù)類型包裝對象
break
case Number: result = "number" //基本數(shù)據(jù)類型包裝對象的父類
break
default: result = "default"
}
println result