天天看點

AndroidStudio下gradle的入門介紹與使用

1 Groovy

Groovy 是沒有類型的 Java 代碼 ,文法更簡潔。形式有點類似腳本語言。被gradle用于建構腳本的語言

1.1 特殊類型

1、範圍

範圍 是一系列的值。

比如 “0..4” 表明包括 整數 0、1、2、3、4。Groovy 還支援排除範圍,“0..<4” 表示 0、1、2、3。還能夠建立字元範圍:“a..e” 相當于 a、b、c、d、e。“a..<e” 包括小于 e 的全部值。

def range = 0..4      

2、集合

def coll = ["Groovy", "Java", "Ruby"]      

3、映射

def hash = [name:"Andy", "VPN-#":45]      

1.2 閉包Closure

閉包是可運作的代碼塊。

它們不須要名稱。能夠在定義之後運作。

1、 閉包的格式

  1. def xxx = {paramters -> code}  //或者  
  2. def xxx = {無參數,純code}  這樣的case不須要->符号

2、 閉包的特點

閉包在Groovy中大量使用,比方非常多類都定義了一些函數,這些函數最後一個參數都是一個閉包。

Groovy中。當函數的最後一個參數是閉包的話,能夠省略圓括号。比方  

AndroidStudio下gradle的入門介紹與使用

事實上辨別doLast為一個函數,函數的最後一個參數為閉包

  1. doLast({  
  2.    println'Hello world!'  
  3. })  

有了圓括号。你會知道 doLast僅僅是把一個Closure對象傳了進去。非常明顯。它不代表這段腳本解析到doLast的時候就會調用println 'Hello world!' 。

可是把圓括号去掉後。就感覺好像println 'Hello world!'馬上就會被調用一樣!

舉例:閉包用于疊代

def acoll = ["Groovy", "Java", "Ruby"]

acoll.each{
 println it
}      

閉包中的 ​

​it​

​ 變量是一個keyword,指向被調用的外部集合的每一個值 — 它是預設值,能夠用傳遞給閉包的參數覆寫它。

1.3 groovy腳本的實質

既然是基于Java的,Groovy會先把xxx.groovy中的内容轉換成一個Java類。比方:

test.groovy的代碼是:

  1. println 'Groovy world!'  

Groovy把它轉換成這種Java類:

運作 groovyc-d classes test.groovy

groovyc是groovy的編譯指令,-d classes用于将編譯得到的class檔案複制到classes目錄下

AndroidStudio下gradle的入門介紹與使用

2 Gradle

Gradle是一種依賴管理工具,基于Groovy語言。面向Java應用為主,它抛棄了基于XML的各種繁瑣配置,取而代之的是一種基于Groovy的内部領域特定(DSL)語言。

用于自己主動化建構、測試、公布打包。

2.1 基本元件

Gradle是一個架構。它定義一套自己的遊戲規則。我們要玩轉Gradle。必需要遵守它設計的規則。以下我們來講講Gradle的基本元件:

Gradle中,每個待編譯的project都叫一個Project。

每個Project在建構的時候都包括一系列的Task。

比方一個Android APK的編譯可能包括:Java源代碼編譯Task、資源編譯Task、JNI編譯Task、lint檢查Task、打包生成APK的Task、簽名Task等。

1.  gradle projects檢視工程資訊

到眼下為止,我們了解了Gradle什麼呢?

l 每個Project都必須設定一個build.gradle檔案。至于其内容。我們留到後面再說。

l 對于multi-projects build。須要在根檔案夾下也放一個build.gradle,和一個settings.gradle。

l 一個Project是由若幹tasks來組成的,當gradlexxx的時候,實際上是要求gradle運作xxx任務。

這個任務就能完畢詳細的工作。

AndroidStudio下gradle的入門介紹與使用
2.  gradle tasks檢視任務資訊

gradleproject-path:tasks 即可。注意,project-path是檔案夾名。後面必須跟冒号。

對于Multi-project。在根檔案夾中,須要指定你想看哪個poject的任務。

隻是你要是已經cd到某個Project的檔案夾了,則不需指定Project-path。

2.2 gradle build的生命周期

AndroidStudio下gradle的入門介紹與使用
  • l Gradle有一個初始化流程,這個時候settings.gradle會運作。
  • l 在配置階段,每一個Project都會被解析。其内部的任務也會被加入到一個有向圖裡,用于解決運作過程中的依賴關系。
  • l 然後才是運作階段。你在gradle xxx中指定什麼任務。gradle就會将這個xxx任務鍊上的所有任務所有按依賴順序運作一遍!
AndroidStudio下gradle的入門介紹與使用

(1)生命周期

eg:Single project build example

​settings.gradle​

println 'This is executed during the initialization phase.'      

​build.gradle​

println 'This is executed during the configuration phase.'

task configured {
    println 'This is also executed during the configuration phase.'
}

task test << {
    println 'This is executed during the execution phase.'
}

task testBoth {
    doFirst {
      println 'This is executed first during the execution phase.'
    }
    doLast {
      println 'This is executed last during the execution phase.'
    }
    println 'This is executed during the configuration phase as well.'
}      
AndroidStudio下gradle的入門介紹與使用

(2)setting.gradle中多project配置

當中setting.gradle在多project的配置中。用于聲明包括的project及其層級關系(平坦和層級結構的project都支援)

include 'project1', 'project2:child', 'project3:child1'      
includeFlat 'project3', 'project4'      

(3)依據生命周期定制task

eg:Logging of start and end of each task execution

​build.gradle​

task ok

task broken(dependsOn: ok) << {
    thrownew RuntimeException('broken')
}

gradle.taskGraph.beforeTask { Task task ->
    println "executing $task ..."
}

gradle.taskGraph.afterTask { Task task, TaskState state ->
    if (state.failure) {
        println "FAILED"
    }
    else {
        println "done"
    }
}      
AndroidStudio下gradle的入門介紹與使用

3 Gradle用途

(1)依賴管理

我們的project可能會用到其它的庫(本地、maven或者ivy)

eg:Declaring dependencies

本地project依賴

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile project(':bugrpt')
}      

遠端庫依賴

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}      

辨別project須要hibernate-core一起編譯,project test須要junit的編譯,第二種寫法group:name:version

dependencies {
    compile 'org.hibernate:hibernate-core:3.6.7.Final'
}      
AndroidStudio下gradle的入門介紹與使用

像這些外部的庫,gradle是通過repository來找到的

eg:Usage of a remote Maven repository

​build.gradle​

repositories {
    maven {
        url "http://repo.mycompany.com/maven2"
    }
}      

eg:Usage of a local Ivy directory

​build.gradle​

repositories {
    ivy {
        // URL can refer to a local directory
        url "../local-repo"
    }
}      

(2)版本号公布

eg:公布project

uploadArchives {
    repositories {
        ivy {
            credentials {
                username "username"
                password "pw"
            }
            url "http://repo.mycompany.com"
        }
    }
}      

(3) 差異管理

比方app生成不同版本号(免費。收費)。适配特殊機型,多管道等須要發多個包。終于能編譯出的apk的數量是由productflavor與BuildType決定的,BuildType預設有debug和release兩種

eg:免費與收費設定不同包名

 productFlavors {

        pay {

            applicationId "me.ghui.gradledemo.pay"

        }

        free {}

    }

AndroidStudio下gradle的入門介紹與使用

eg:buildTypes 相應的不同版本号

android {

​    buildTypes {​

​        debug {​

​            applicationIdSuffix ".debug"​

​        }​

​        jnidebug { ​

​            initWith(buildTypes.debug)

​            packageNameSuffix ".jnidebug"​

​            jniDebuggable true​

​        }​

​    }​

​}​

​對于每一種buildTypes 會建立對應的ssemble<BuildTypeName>任務,比方debug會自己主動建立assembleDebug任務​

​ ​

eg:多管道打包

AndroidStudio下gradle的入門介紹與使用
AndroidStudio下gradle的入門介紹與使用

4 gradle wrapper

gradlew通過包裹了gradle,然後通過配置中url下載下傳。存儲到使用者檔案夾 ​

​$USER_HOME/.gradle/wrapper/dists​

​.

 啟動圖形界面

gradle --gui

附錄 gradle腳本基礎

1 project和task

task表示建構的一次原子操作,包括編譯類、建立jar包、公布到repository、生成javadoc等,而project通常包括多個task

task hello {
    doLast {
        println 'Hello world!'
    }
}      

這個腳本定義了一個叫做hello的task,而且加入了一個action,這個action實際上是由groovy語言編寫的閉包。更簡潔的寫法

task hello << {
    println 'Hello world!'
}      

> gradle -q hello

Hello world!      

2 task依賴

project('projectA') {
    task taskX(dependsOn: ':projectB:taskY') << {
        println 'taskX'
    }
}

project('projectB') {
    task taskY << {
        println 'taskY'
    }
}      

3 能夠動态建立task,并通過api操作task

4.times { counter ->
    task "task$counter" << {
        println "I'm task number $counter"
    }
}
task0.dependsOn task2, task3      

4 task能夠定義屬性

task myTask {
    ext.myProperty = "myValue"
}

task printTaskProperties << {
    println myTask.myProperty
}      

5 設定預設

defaultTasks 'clean', 'run'

task clean << {
    println 'Default Cleaning!'
}

task run << {
    println 'Default Running!'
}

task other << {
    println "I'm not a default task!"
}      

6 能夠加入HOOK

task distribution << {
    println "We build the zip with version=$version"
}

task release(dependsOn: 'distribution') << {
    println 'We release now'
}

gradle.taskGraph.whenReady {taskGraph ->
    if (taskGraph.hasTask(release)) {
        version = '1.0'
    } else {
        version = '1.0-SNAPSHOT'
    }
}      
AndroidStudio下gradle的入門介紹與使用

7 定位task

1)使用task的名字

println hello.name      

2)使用tasks collection

println tasks.hello.name      

3)使用project:task路徑定位

tasks.getByPath(':projectA:hello').path      

8 配置task

Configuring a task - with closure

task copy(type: Copy) {
   description 'Copies the resource directory to the target directory.'
   from 'resources'
   into 'target'
   include('**/*.txt', '**/*.xml', '**/*.properties')
}      
下一篇: 相冊