Groovy在gradle中的應用
Groovy
一種基於JVM(Java虛擬機)的敏捷開發語言,能夠與 Java 代碼很好地結合。
Groovy特點:
1) Groovy 的鬆散的 Java 語法允許省略分號和修改符。
2) Groovy 的所有內容都爲 public,除非另行指定。
3) Groovy 允許定義簡單腳本,同時無需定義正規的 class對象。
4) Groovy 語法允許省略變量類型。
Eclipse安裝Groovy插件:https://github.com/groovy/groovy-eclipse/wiki
Groovy用法舉例:
// 定義函數
def repeat(val) {
for(i = 0; i < 5; i++) {
println val
}
}
repeat("hello")
// 定義集合
def range = 0..4
println range
def coll = ["Groovy", "Java", "Ruby"]
println coll
coll.add("Python")
coll << "Small Talk"
// 定義map映射
def hash = [name:"Andy", "VPN-#":45]
println hash
println hash.getClass()
println hash.get("name")
// 閉包
// 默認關鍵字it,指向被調用的外部集合的每一個值
hash.each {
println it
}
// 自定義變量
hash.each { value ->
println value
}
// 使用多個參數
hash.each { key, value ->
println "${key}:${value}"
}
// 閉包類似函數指針的用法
def combine = { val1, val2 ->
return "${val1} + ${val2}"
}
println combine("Good", "Luck")
// 類
class Song {
def name
def artist
def genre
}
def sng2 = new Song(name:"Kung Fu Fighting", genre:"Disco")
sng2.artist = "Jack"
println sng2.name
Gradle
定義任務(Task)以及任務間的依賴(Dependency),形成一個有向無環圖。當在根目錄下執行gradle時,先解析執行根目錄下的setting.gradle和build.gradle兩個文件,然後依次解析執行每個module目錄下的build.gradle文件。
生命週期:
1. 初始化(Initialization)
初始化階段,會去讀取根工程中setting.gradle中的include信息,決定有哪幾個工程加入構建,創建project實例,比如下面有三個工程:
include ':app', ':lib1', ':lib2'
gradle運行時系統會爲settings.gradle文件生成一個settings隱含對象,會爲每個build.gradle生成一個project對象,這些文件中調用的方法沒有顯示其實都是調用其對應的隱含對象的方法。比如上面這句話就是執行了一行代碼:
settings.include(":app")
對於settings對象和project對象的更多方法和屬性,可以從官網查詢。
2. 配置(Configuration)
配置階段,會去執行所有工程的build.gradle腳本,配置project對象,一個對象由多個任務組成,此階段也會去創建、配置task及相關信息。
3. 執行(Execution)
運行階段,根據gradle命令傳遞過來的task名稱,執行相關依賴任務。
task
task hello {
doFirst {
println 'first'
}
doLast {
println 'last'
}
println 'hello task'
}
task hello2 << {
println 'hello2'
}
task hello3(dependsOn: hello) {
doLast {
println "hello3"
}
}
對生命週期的響應
在經歷生命週期的不同階段時,構建腳本會接受到不同的通知消息(Notification),可以捕獲這些消息並做一些相應的處理。
whenTaskAdded:當一個task被添加的時候
tasks.whenTaskAdded { task ->
switch (task.name) {
case 'bfd':
task.dependsOn 'assembleDebug'
break;
case 'bfr':
setAllConfig(app_version, online, version_name)
task.dependsOn 'assembleRelease'
break;
}
}
task bfd << {}
whenReady:配置完成後
gradle.taskGraph.whenReady { taskGraph ->
if (taskGraph.hasTask(release)) {
version = '1.0'
} else {
version = '1.0-SNAPSHOT'
}
}
beforeTask/afterTask:task執行前後
gradle.taskGraph.afterTask { Task task, TaskState state ->
if (state.failure) {
println "FAILED"
} else {
println "done"
}
}
productFlavors使用
在productFlavors下可以建立多個不同的分支
- 每個分支可以使用不同的配置文件。defaultConfig是共用的默認配置,在這裏面添加的配置會出現在生成的BuildConfig.java文件中。在productFlavors每個分支裏定義的配置會覆蓋默認配置。如下配置,在不同的應用市場採用不同的開啓或關閉自動更新的功能。
android {
defaultConfig {
applicationId "com.magic.wdl.animatedlinearlayout"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
...
buildConfigField "boolean", "AUTO_UPDATES", "true"
}
...
productFlavors {
wandoujia {
buildConfigField "boolean", "AUTO_UPDATES", "false"
}
huawei {
buildConfigField "boolean", "AUTO_UPDATES", "true"
}
}
}
- 每個分支會對應一個dataSet,可以對不同分支的dataSet使用不同的資源文件,比如不同的分支使用不同的包名或logo。如下配置,在不同應用市場使用不同的包名:
android {
...
productFlavors {
wandoujia {
}
huawei {
}
}
}
huawei/res/values/string.xml
<resources>
<string name="app_name">華爲市場包</string>
</resources>
wandoujia/res/values/string.xml
<resources>
<string name="app_name">豌豆莢市場包</string>
</resources>
參考:
http://www.ibm.com/developerworks/cn/education/java/j-groovy/j-groovy.html
http://tech.meituan.com/mt-apk-adaptation.html
http://jiajixin.cn/2015/08/07/gradle-android/