一、Gradle是目前Android主流的構(gòu)建工具、我們?cè)谧鲰?xiàng)目的時(shí)候、有很多的配置都會(huì)放在項(xiàng)目的build.gradle文件中進(jìn)行。
如版本、信息、包名、一些第三方依賴、或者打包時(shí)用到的簽名、混淆文件信息等。android開發(fā)離不開gradle。我們經(jīng)常會(huì)不可避免的與gradle打交道。所以學(xué)習(xí)gradle是很有必要的事情。
Gradle 是一個(gè)配置腳本,它的背后是由Groovy Language、 Gradle DSL、 Android DSL幾門語言。其中dsl是指領(lǐng)域特定語言。只能用于特定的某個(gè)流域。今天我們先來學(xué)習(xí)Groovy。
Groovy是一門jvm語言。它最終會(huì)編譯成class文件在jvm上執(zhí)行。所以它與java類似。甚至可以與java進(jìn)行混寫。groovy的優(yōu)勢(shì)在于它有大量自己的特性與語法。更加方便的讓我們以更少的代碼完成與java同樣的功能。
二、配置環(huán)境
1、配置java環(huán)境變量 新建用戶變量JAVA_HOME、這里注意不要加;與bin路徑:正確為 D:\AndroidStudio\jre\ 錯(cuò)誤為 D:\AndroidStudio\jre\bin或者D:\AndroidStudio\jre\bin;
將JAVA_HOME 用戶變量設(shè)置到系統(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目錄下 因?yàn)?此目錄下有g(shù)radle.bat 文件
3、驗(yàn)證是否配置成功
打開控制臺(tái) cmd 執(zhí)行 gradle命令 如圖下所示為成功
二、groovy語言基礎(chǔ)(與世界說句hello)
首先我們先來寫一個(gè)學(xué)習(xí)任何語言的第一步先寫個(gè)helloWorld出來
1、創(chuàng)建一個(gè)build.gradle 文件(注意。文件名改成xx.gradle是不行的) 書寫以下代碼,并執(zhí)行g(shù)radle helloworld
解釋一下。grdle 執(zhí)行的是task 我們創(chuàng)建了一個(gè)helloworld的task 并打印一個(gè)println 輸出hello world 函數(shù)
task(helloworld).doLast {
println "hello world"
}
恭喜各位。已經(jīng)成功入門,進(jìn)入groovy的世界了。
三、變量
對(duì)于groovy來說 它也是一種強(qiáng)類型的語言但是,它不用像java一樣指定某個(gè)變量的類型,它會(huì)自己去推斷。定義變量的方法 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ù)類型。這里可以看出 它其實(shí)和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"
}
這里大家看到定義了幾個(gè)方法、其中有很多是可以省略的 比如 返回值 return 語句 省略 return 、方法值參數(shù)可以省略類型、等。使用方法與java 一致 直接調(diào)用就可以了 。
五、String類型的拼接
對(duì)于String類型的拼接在我們AndroidManifest.xml文件中最為常見。我們先看一段代碼
在圖片上的代碼中我們看到紅框部分中標(biāo)記的 applicationid 為我們的報(bào)名。我們可以在gradle中定義不同的報(bào)名來適配我們 androidManifest文件中使用。這樣我們修改報(bào)名之后。只需要修改一個(gè)位置。不用到androidManifest文件中去全局替換了。以下為groovy書寫。定義了a 與b變量 在c變量中使用%{x}進(jìn)行引用。我們看我們打印出來的返回值,已經(jīng)是拼接后的值了
def a = 1
def b = "hello"
def c = "a=${a}, b=$"
println c
outputs:
a=1, b=hello
六、閉包
groovy中有一個(gè)特殊的類型叫做閉包、作為一種數(shù)據(jù)類型存在??梢宰鰹橐粋€(gè)方法的參數(shù)與返回值。也可以作為一個(gè)變量而存在
{ 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ù)、那么它有一個(gè)隱藏參數(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 = [:]
以上相當(dāng)于定義了兩個(gè)空的object 集合 第一個(gè)為list 第二個(gè)為map
def test = [100, "hello", true]
def test = ["id":1, "name":"renyugang", "isMale":true]
對(duì)于list來講 我們來看看怎么使用
def test = [100, "hello", true]
test[1] = "world" //將index 為1 的元素值替換為world
println test[0] //打印 index為0的元素
println test[1] //打印 index為1的元素
test << 200 // 添加一個(gè)值為200的元素
println test.size //打印list的大小
outputs:
100
world
4
以上代碼為使用。其中有一個(gè)部分 為<< 位操作符。這個(gè)操作符與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對(duì)應(yīng)的方法沒有差別。想要遍歷怎么辦。猜一下
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 //設(shè)置 key為one 的值為2
test.one= 900 //設(shè)置 key為one 的值為900
def keySet = text.keySet()
for (def key : keySet){
println "${key}+${text[key]}"
}
}
對(duì)于集合的遍歷剛才我們已經(jīng)通過與java 相同的方式進(jìn)行了演示,如果我們想通過groovy的方式改怎么做的
我們可以查看另外一個(gè)文檔http://docs.groovy-lang.org/latest/html/groovy-jdk/index-all.html
我們可以看到又一個(gè)each方法 他是使用閉包的方式進(jìn)行遍歷的
但是很不幸的是 list的each方法點(diǎn)進(jìn)去是下面這樣的
大爺?shù)臎]有示例方法不知道怎么用啊,我們?cè)倏纯磎ap吧
這個(gè)還好有示例方法我們來依葫蘆畫瓢
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)他有兩種使用方法,一種是 閉包是兩個(gè) 變量 key value 它對(duì)應(yīng)的就是
我們map 中的key value 第二種方式 就是是一個(gè) entry 我們知道 在java 的map 中 每個(gè)元素是用entry 保存的所以這樣也很符合java數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì),這里的entry 是可以省略的。上邊已經(jīng)說到 如果閉包中只有一個(gè)元素變量的話是可以省略的。大家可以試一下
好了map 搞定了。list咋辦。猜吧(其實(shí)文檔應(yīng)該能找到)
def textTwo = [ 1, 2, 3, 4, 5]
textTwo.each{
println it
}
output
1
2
3
4
5
完美
八、io
groovy 相比于java io 方便很多。當(dāng)然我們完全可以使用 groovy 支持的java的解析方式用來解析。這個(gè)就不演示了。大家可以試試。我們這次演示的是groovy 提供的閉包的方式進(jìn)行。
1、文件讀取
我們查看文檔的話我們可以看到 支持file 讀取的 有 eachByte eachLine 等
以上是api 文檔中的一部分 但是還是沒有示例代碼。一萬句mmp,幸虧有萬能的翻譯
可以看到參數(shù) 說是 第一個(gè)參數(shù)是行 第二個(gè)是可選參數(shù) 為從1開始的行號(hào)。來吧繼續(xù)猜代碼怎么寫
我們?cè)倏纯?這個(gè)方法是誰得
這么簡(jiǎn)單得翻譯軟件也可以剩下了 。 這個(gè)方法是 class File的方法 ,繼續(xù)猜。java 咋拿File對(duì)象 這里咋拿
然后按照閉包的方式寫
來吧 groovy 不是號(hào)稱 自動(dòng)推斷類型么
def file = new def(text1.txt);
然后 mmp 報(bào)錯(cuò),看來它還沒成神
然后試了下
def file = new File("text1.txt");
不報(bào)錯(cuò)了
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é)點(diǎn)的name屬性
println xml['declare-styleable'].@name[0]
// 訪問declare-styleable的第三個(gè)子節(jié)點(diǎn)的內(nèi)容
println xml['declare-styleable'].attr[2].text()
outputs:
CircleView
renyugang
Groovy 出了以上新特性以外還有其他的新特性
比如。默認(rèn)的get set方法。groovy 中定義一個(gè)class 他的屬性是默認(rèn)存在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"
可以簡(jiǎn)寫為:
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、簡(jiǎn)潔的三元表達(dá)式
def result = name != null ? name : "Unknown"
// 省略了name
def result = name ?: "Unknown"
4、簡(jiǎn)潔的非空判斷
if (order != null) {
if (order.getCustomer() != null) {
if (order.getCustomer().getAddress() != null) {
System.out.println(order.getCustomer().getAddress());
}
}
}
可以簡(jiǎn)寫為:
println order?.customer?.address
使用斷言
在Groovy中,可以使用assert來設(shè)置斷言,當(dāng)斷言的條件為false時(shí),程序?qū)?huì)拋出異常,因?yàn)槲覀兪褂肎roovy是用來寫插件的。出錯(cuò)了直接拋。讓使用插件的改 我們沒必要捕獲處理異常信息的。所以對(duì)異常處理不涉獵。
def check(String name) {
assert name
assert name?.size() > 3
}
1、對(duì)于switch 語句來講。groovy 支持更豐富的條件語句
def x = "haha"
def result = ""
switch (x) {
case String:result = "string" //String
break
case "foo": //字符串
result = "found foo"
case "bar": //因?yàn)樯线厸]有break 這里的判斷允許失效。會(huì)執(zhí)行下一個(gè)語句
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ù)類型包裝對(duì)象
break
case Number: result = "number" //基本數(shù)據(jù)類型包裝對(duì)象的父類
break
default: result = "default"
}
println result