【Android】初探自動化構建-Gradle中的Groovy

Groovy&Gradle

Groovy是基於JVM的一種腳本語言。

Gradle是新一代的自動化構建工具(似Ant+Ivy,Maven),其核心功能由Java實現。
幷包含由Groovy編寫的自動化構建領域特定語言(DSL)。
Gradle的構建腳本(build.gradle)就是一個可執行的Groovy腳本。

Groovy的語法特性

Groovy底層由Java實現,幾乎100%地支持Java語法
還融合了Python等腳本語言的特性,可以更加簡潔:

基本語法

  1. 省略分號:語句後的分號(;)是可選的。
  2. 省略括號:如果方法調用有參數傳遞,括號是可選的,如:println 'Hello World'apply plugin:'java'等價於apply([plugin:'java'])
  3. 省略return:返回語句return是可選的,默認返回方法體最後一條語句的值或null,如無需返回應聲明爲void
  4. 構造器成員方法默認都是public的。
  5. 自動生成getter/setter,可以通過點號(.)操作成員,底層自動調用。
  6. ==在底層自動調用equals
  7. assert語句會一直生效,無需指定-ea-enableassertion

更多特性

  1. 類型弱化:def佔位java.lang.Object,運行時自動分析 且 引用的類型可變。

  2. 命名參數:默認構造 + setter賦值

    class Person{
        String name
        Integer age
    }
    
    def Person p = new Person(name:'Name1',age:18);
    assert p.age == 18
    
  3. 閉包
    閉包是一個java.lang.Closure類型的代碼塊,可以賦值給變量,也可以作爲方法調用。

    隱式閉包
    沒有顯式定義參數的閉包都可以訪問一個it,代表調用這個閉包傳過來的第一個參數,沒傳爲null

    def increment={
        assert it == 12
    }
    increment(12)
    

    顯式閉包

    def sum = { one, two, three ->
        one + two + three
    }
    println sum(1, 3, "14") // !!!: 414
    

    返回值
    閉包總是會返回值(return返回、最後一條語句的值,或null)。

    閉包作爲方法參數

    void echo(Closure<Object> closure, def obj){
        println closure()+obj
    }
    echo({10},1)
    

    閉包委託
    閉包代碼在委託上執行,默認委託是閉包的所有者,如:groovy.lang.Script。閉包的隱式成員delegate允許改變默認的所有者。

    class Person{
        String name
        Integer age
    
        void update(Closure closure){
            closure.resolveStrategy = Closure.DELEGATE_ONLY
            closure.delegate = this
            closure()
        }
    }
    
    Person person = new Person(name:"aCk",age:18);
    person.update {
        name = name.toUpperCase()
        age++
    }
    println person.name+' : '+person.age // ACK : 19
    
  4. 字符串
    三種定義方式:

    def s1 = 'Hello';
    def s2 = "World";
    def s3 = """
        Hello,
        Groovy;
    """
    

    其中雙引號的串中可以有插值計算操作:

    def s1 = 'groovy';
    def s2 = "Hello ${s1.capitalize()}"
    assert s2=="Hello Groovy"
    
  5. List與Map

    // java.util.ArrayList
    def list = ['S1','S2']; 
    
    list << 'S3' // list.add("S3");
    
    assert list[2]=='S3' // list.get(2);
    
    list.each { /* it -> */ // 默認提供迭代器it
        println it
    }
    
    
    // java.lang.LinkedHashMap
    def map = ['K1':'V1', 'K2':'V2']
    
    assert map.K1 == 'V1'
    assert map['K2'] == 'V2'
    
    assert map.size() == 2
    
    map['K3'] = 'V3'
    
    map.each { key,val ->
        println "key $key's value is $val"
    }
    
  6. GDK(Groovy Development Kit)
    GDK拓展了JDK,並提供了很多更便捷的方法。具體可參見:http://groovy.codehaus.org/groovy-jdk/

new File().eachLine{ line ->
    println line
}

Gradle中的Groovy

每個build.gradle構建腳本都至少有一個對應的org.gradle.api.Project實例,多數情況下腳本的屬性和方法都委託給了這個實例。

// project.apply([plugin:''])
apply plugin: 'com.android.application'

// project.android({})
android {
    // closure.delegate|owner.compileSdkVersion(28)
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.chavin"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    dataBinding {
        // closure.delegate|owner.setEnabled(true)
        enabled = true
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章