Gradle系列(一):Groovy基礎(chǔ)
Gradle系列(二):AndroidStudio的Gradle簡介
Gradle系列(三):項目實踐
前言
關(guān)于Gradle的文章很多掏呼,但是大多是以一些技巧為主,東敲西打看了之后可能解決了一些問題,但對于新的需求,gradle如何運用到項目中還是一知半解温艇。我準(zhǔn)備稍微深層一點了解gradle卿吐,從基本語法開始到如何用到實際項目中,在此我把gradle的學(xué)習(xí)分成三個部分母蛛,分享給大家:
- 第一部分:Groovy基礎(chǔ)
- 第二部分:android studio中g(shù)radle插件簡介
- 第三部分:項目實踐
Groovy基礎(chǔ)
項目中build.gradle都是用groovy寫的因宇,不了解一下groovy怎么能看得懂呢七婴?這里只需要知道groovy的一些基礎(chǔ)知識,比如怎么定義變量察滑,定義方法打厘,方法怎么使用,閉包的使用贺辰,這些就差不多了户盯。
首先要知道groovy是一種腳本語言,有下面三個特點:
- 是一種動態(tài)語言,不需要編譯直接生效
- 是一種DSL魂爪,即Domain Specific Language(專門領(lǐng)域的編程語言先舷,所以比較難閱讀)
- Groovy基于Java同時也像是一種腳本語言(基于java艰管,這個看下面基本語法就明白了)
基本語法
- ****定義基本變量:****
def variable1 = 1 //可以不使用分號結(jié)尾
def varable2 = "I am a person"
def int x = 1 //變量定義時滓侍,也可以直接指定類型
- ****字符串:****
1 單引號''中的內(nèi)容嚴(yán)格對應(yīng)Java中的String,不對$符號進(jìn)行轉(zhuǎn)義
def singleQuote='I am $ dolloar' //輸出就是I am $ dolloar
2 雙引號""的內(nèi)容則和腳本語言的處理有點像牲芋,如果字符中有$號的話撩笆,則它會$表達(dá)式先求值捺球。
def doubleQuoteWithoutDollar = "I am one dollar" //輸出 I am one dollar
def x = 1
def doubleQuoteWithDollar = "I am $x dolloar" //輸出I am 1 dolloar
3 三個引號'''xxx'''中的字符串支持隨意換行 比如
def multieLines = ''' begin
line 1
line 2
end '''
- ****定義函數(shù):****
String testFunction(arg1,arg2){//無需指定參數(shù)類型
...
}
def nonReturnTypeFunc(){
last_line //最后一行代碼的執(zhí)行結(jié)果就是本函數(shù)的返回值
}
//如果指定了函數(shù)返回類型,則可不必加def關(guān)鍵字來定義函數(shù)
String getString(){
return "I am a string"
}
- ****函數(shù)調(diào)用:****
println("test") ---> println "test"http:// 可以不加括號夕冲,但是建議:自定義的方法調(diào)用加上括號氮兵! API提供的方法調(diào)用可以不用括號
****數(shù)據(jù)類型:****
** java中的基礎(chǔ)數(shù)據(jù)類型**
在Groovy中所有事物都是對象,int count = 12; //這里的count其實是Integer類型歹鱼,其他的使用和Java一樣
- ****容器類****
1.List
變量定義:List變量由[]定義泣栈,也可以賦予一些初始值,比如
def aList = [5,'string',true] //List由[]定義弥姻,其元素可以是任何對象
變量存饶掀:可以直接通過索引存取,而且不用擔(dān)心索引越界庭敦。如果索引超過當(dāng)前鏈表長度疼进,List會自動
往該索引添加元素
assert aList[1] == 'string'
assert aList[5] == null //第6個元素為空
aList[100] = 100 //設(shè)置第101個元素的值為10
assert aList[100] == 100
那么,aList到現(xiàn)在為止有多少個元素呢秧廉?
println aList.size ===>結(jié)果是101
2.Map
Map由[:]定義伞广,注意其中的冒號。冒號左邊是key疼电,右邊是Value嚼锄。key必須是字符串,value可以是任何對象澜沟。另外灾票,key可以用''或""包起來,也可以不用引號包起來茫虽。比如
def mapData = [:]
mapData.put("name","test name")
println(mapData.get("name"))//輸出“test name”
3.閉包(Closure)
- 定義:閉包刊苍,是一種數(shù)據(jù)類型,它代表了一段可執(zhí)行的代碼濒析。他可以作為方法的參數(shù)正什,或者返回值,也可以獨立運行
//自定義一個閉包
def aClosure = { //閉包是一段代碼号杏,所以需要用花括號括起來..
String param -> println("test closure,para = $param") //這個箭頭很關(guān)鍵婴氮。箭頭前面是參數(shù)定義,箭頭后面是代碼
return 200 //返回值
}
//調(diào)用這個閉包:(用call方法或者直接蠶食寫在括號里面)
def count = aClosure.call("dml")
// def count2 = aClosure("dml")
println("$count")
在Gradle控制臺看一下輸出:
上面說到Closure也可以作為方法的參數(shù)盾致,在Android Gradle中有不少這樣的用法主经,比如:
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// 輸出apk名稱為boohee_v1.0_2015-01-15_wandoujia.apk
def fileName = "boohee_v${defaultConfig.versionName}_${variant.productFlavors[0].name}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
}
}
分析一下這里代碼是什么意思:
這里debug的配置代碼:
作用是根據(jù)多渠道打包配置,重新命名APK(這里的實例代碼是在productFlavors中配置了“wandoujia”)庭惜,這里不考慮這個配置罩驻,看下這段代碼用到了
applicationVariants.all和variant.outputs.each兩個Android Gradle插件API提供了兩個方法,第一個方法大致意思是獲取project對應(yīng)的app护赊,第二個方法大致意思是遍歷生成的所有debug和release的apk惠遏,并且重命名砾跃!
看下each這個方法,參數(shù)就是一個Closure节吮,并且遍歷自己抽高,把每一個item傳入這個自定義的Closure執(zhí)行,而在這個Closure中就是我們自己的實現(xiàn):傳入
output變量透绩,對output重命名翘骂。Closure有點類似java的函數(shù)回調(diào)。
- 閉包使用注意:
1.如果一個方法的最后一個參數(shù)是Closure那么帚豪,可以不用圓括號雏胃,比如上面的all方法和each方法
2.如果閉包沒有定義參數(shù),那么它默認(rèn)擁有參數(shù)it志鞍,類似于java的this:
def bClosure = {println("param = $it")
}
bClosure.call("this closure瞭亮!") //輸出: param = this closure!
3.閉包的參數(shù)怎么傳
比如上面的
variant.outputs.each方法固棚,雖然知道他要傳入closure參數(shù)统翩,但是這個closure參數(shù)傳幾個呢 ? 我們無法確定此洲,只有通過API:
才能知道這個closure只接受一個參數(shù)厂汗!如果我們傳入多參數(shù)的closure這里會報錯,所以說closure和上下文有很強的關(guān)聯(lián)性呜师,我們必須熟悉一些api才能很好地傳入closure娶桦!
-
IO操作
Groovy提供了簡單的讀取文件的方法,通過一個實例了解一下:
在我們公司項目中汁汗,一些基礎(chǔ)功能比如網(wǎng)絡(luò)模塊衷畦,通用控件等單獨編譯成aar文件,放到項目的根目錄lib文件夾知牌。
我們可以利用gradle的IO操作讀取lib里面的file名稱:
//獲取基礎(chǔ)庫版本號
def path = rootProject.getRootDir().getAbsolutePath() + "/libs"
def configFile = new File(path)
def files = configFile.listFiles()
def aar1 = files[0].getName()
def aar2 = files[1].getName()
println(aar1 )
println(aar2 )
輸出:
那這個有什么用呢祈争,后面第三部分的實踐會講到。
其他
Groovy還有一些技巧:
- 讀取xml文件角寸,比如讀取manifest.xml文件信息
- 封裝獨立的工具類tools.gradle菩混,比如獲取Android版本名稱,版本號扁藕,拷貝文件等IO操作
這些等用到的時候再說