gradle構(gòu)建

百度百科

Gradle是一個(gè)基于Apache Ant和Apache Maven概念的項(xiàng)目自動(dòng)化構(gòu)建工具到踏。它使用一種基于Groovy的特定領(lǐng)域語言(DSL)來聲明項(xiàng)目設(shè)置,拋棄了基于XML的各種繁瑣配置辐怕。主要用于Java語言。

Groovy對自己的定義就是:Groovy是在 java平臺上的贡茅、 具有像Python秘蛇, Ruby 和 Smalltalk 語言特性的靈活動(dòng)態(tài)語言, Groovy保證了這些特性像 Java語法一樣被 Java開發(fā)者使用顶考。Groovy 是一門JVM 語言,也就是妖泄,Groovy 的代碼最終也會(huì)被編譯成JVM 字節(jié)碼驹沿,交給虛擬機(jī)去執(zhí)行。

Groovy 基本語法

變量

在groovy 中蹈胡,沒有固定的類型渊季,變量可以通過def關(guān)鍵字引用,比如:

def name = 'Andy'

我們通過單引號引用一串字符串的時(shí)候這個(gè)字符串只是單純的字符串罚渐,但是如果使用雙引號引用却汉,在字符串里面還支持插值操作,

def name = 'Andy'
def greeting = "Hello, $name!"

方法

類似 python 一樣荷并,通過def關(guān)鍵字定義一個(gè)方法合砂。方法如果不指定返回值,默認(rèn)返回最后一行代碼的值源织。

def square(def num) {
    num * num
}
square 4

Groovy 也是通過Groovy 定義一個(gè)類:

class MyGroovyClass {
    String greeting
    String getGreeting() {
        return 'Hello!'
    }
}
  • 在Groovy 中翩伪,默認(rèn)所有的類和方法都是pulic的,所有類的字段都是private的谈息;

  • 和java一樣缘屹,我們通過new關(guān)鍵字得到類的實(shí)例,使用def接受對象的引用:def instance = new MyGroovyClass()

  • 而且在類中聲明的字段都默認(rèn)會(huì)生成對應(yīng)的setter,getter方法侠仇。所以上面的代碼我們可以直接調(diào)用instance.setGreeting 'Hello, Groovy!'轻姿,注意,groovy 的方法調(diào)用是可以沒有括號的逻炊,而且也不需要分號結(jié)尾互亮。除此之外,我們甚至也可以直接調(diào)用嗅骄;

  • 我們可以直接通過instance.greeting這樣的方式拿到字段值胳挎,但其實(shí)這也會(huì)通過其get方法,而且不是直接拿到這個(gè)值溺森。

閉包

在Groovy 中有一個(gè)閉包的概念慕爬。閉包可以理解為就是 Java 中的匿名內(nèi)部類窑眯。閉包支持類似lamda形式的語法調(diào)用。如下:

def square = { num ->
    num * num
}
square 8

如果只有一個(gè)參數(shù)医窿,我們甚至可以省略這個(gè)參數(shù)磅甩,默認(rèn)使用it作為參數(shù),最后代碼是這樣的:

Closure square = {
    it * it
}
square 16

安裝

下載官網(wǎng)的壓縮包姥卢,下載地址https://guides.gradle.org
解壓卷要,

image.png

配置本地的環(huán)境變量

image.png

驗(yàn)證

image.png

第一次輸入gradle -v會(huì)在本地用戶文件夾生成.gradle的文件夾,是Gradle的本地倉庫

Eclipse安裝Gradle

現(xiàn)在新版本的Eclipse/oxygen已經(jīng)集成了Geadle
創(chuàng)建一個(gè)新項(xiàng)目独榴,觀察是否有Gradle僧叉,若有就注明,已經(jīng)集成棺榔,不需要下載插件了瓶堕。

image.png

若無,需要下載Buildship插件

help---》 Eclipse Markeplace....

image.png

安裝完成后重啟Eclipse症歇,觀察是否出現(xiàn)Gradle項(xiàng)目郎笆。

Eclipse創(chuàng)建Gradle項(xiàng)目

image.png
image.png
image.png
image.png
image.png
image.png

Gradle的編譯周期

在解析 Gradle 的編譯過程之前我們需要理解在 Gradle 中非常重要的兩個(gè)對象。ProjectTask忘晤。

每個(gè)項(xiàng)目的編譯至少有一個(gè) Project,一個(gè) build.gradle就代表一個(gè)project,每個(gè)project里面包含了多個(gè)task,task 里面又包含很多action宛蚓,action是一個(gè)代碼塊,里面包含了需要被執(zhí)行的代碼设塔。

在編譯過程中凄吏, Gradle 會(huì)根據(jù) build 相關(guān)文件,聚合所有的projecttask壹置,執(zhí)行task 中的 action竞思。因?yàn)?build.gradle文件中的task非常多,先執(zhí)行哪個(gè)后執(zhí)行那個(gè)需要一種邏輯來保證钞护。這種邏輯就是依賴邏輯盖喷,幾乎所有的Task 都需要依賴其他 task 來執(zhí)行,沒有被依賴的task 會(huì)首先被執(zhí)行难咕。所以到最后所有的 Task 會(huì)構(gòu)成一個(gè) 有向無環(huán)圖(DAG Directed Acyclic Graph)的數(shù)據(jù)結(jié)構(gòu)课梳。

編譯過程分為三個(gè)階段:

  • 初始化階段:創(chuàng)建 Project 對象,如果有多個(gè)build.gradle余佃,也會(huì)創(chuàng)建多個(gè)project.

  • 配置階段:在這個(gè)階段暮刃,會(huì)執(zhí)行所有的編譯腳本,同時(shí)還會(huì)創(chuàng)建project的所有的task爆土,為后一個(gè)階段做準(zhǔn)備椭懊。

  • 執(zhí)行階段:在這個(gè)階段,gradle 會(huì)根據(jù)傳入的參數(shù)決定如何執(zhí)行這些task,真正action的執(zhí)行代碼就在這里.

Gradle的目錄

image.png

src文件夾

src/main/javasrc/test/java是和一般的Java項(xiàng)目一樣步势,存放源碼配置的位置氧猬,方便調(diào)試背犯,和``·src```是一樣的。

gradle文件夾

存放gradle的版本里面有一個(gè) wrapper文件夾

gradlw wrapper 包含一些腳本文件和針對不同系統(tǒng)下面的運(yùn)行文件盅抚。wrapper 有版本區(qū)分漠魏,但是并不需要手動(dòng)去下載,當(dāng)運(yùn)行腳本的時(shí)候妄均,如果本地沒有會(huì)自動(dòng)下載對應(yīng)版本文件柱锹。

image.png
image.png

build.gradle

配置整個(gè)projeck的項(xiàng)目的構(gòu)建的依賴

apply plugin: 'java-library' 聲明:我們構(gòu)建的是一個(gè)java的library

image.png

setting.gradle

這個(gè) setting 文件定義了哪些module 應(yīng)該被加入到編譯過程,對于單個(gè)module 的項(xiàng)目可以不用需要這個(gè)文件丰包,但是對于 multimodule 的項(xiàng)目就需要這個(gè)文件禁熏,否則gradle 不知道要加載哪些項(xiàng)目。這個(gè)文件的代碼在初始化階段就會(huì)被執(zhí)行邑彪。

image.png

gradlew和gradlew.bat

gradkew的配置和運(yùn)行文件

image.png

Gradle 的 Task

Task的介紹

一個(gè)Task代表一個(gè)構(gòu)建工作的原子操作匹层,例如編譯calsses或者生成javadoc。
Gradle中锌蓄,每一個(gè)待編譯的工程都叫一個(gè)Project。每一個(gè)Project在構(gòu)建的時(shí)候都包含一系列的Task撑柔。比如一個(gè)Android APK的編譯可能包含:Java源碼編譯Task瘸爽、資源編譯Task、JNI編譯Task铅忿、lint檢查Task剪决、打包生成APK的Task、簽名Task等檀训。插件本身就是包含了若干Task的柑潦。

  • 一個(gè)Task包含若干Action。所以峻凫,Task有doFirst和doLast兩個(gè)函數(shù)渗鬼,用于添加需要最先執(zhí)行的Action和需要和需要最后執(zhí)行的Action。
    Action就是一個(gè)閉包荧琼。閉包譬胎,英文叫Closure,是Groovy中非常重要的一個(gè)數(shù)據(jù)類型或者說一種概念命锄。
  • Task創(chuàng)建的時(shí)候可以通過 type: SomeType 指定Type堰乔,Type其實(shí)就是告訴Gradle,這個(gè)新建的Task對象會(huì)從哪個(gè)基類Task派生脐恩。比如镐侯,Gradle本身提供了一些通用的Task,最常見的有Copy 任務(wù)驶冒。Copy是Gradle中的一個(gè)類苟翻。當(dāng)我們:task myTask(type:Copy)的時(shí)候,創(chuàng)建的Task就是一個(gè)Copy Task怜俐。
  • 當(dāng)我們使用 taskmyTask{ xxx}的時(shí)候汞扎,花括號就是一個(gè)closure景鼠。
  • 當(dāng)我們使用taskmyTask << {xxx}的時(shí)候鲫构,我們創(chuàng)建了一個(gè)Task對象结笨,同時(shí)把closure做為一個(gè)action加到這個(gè)Task的action隊(duì)列中,并且告訴它“最后才執(zhí)行這個(gè)closure”
task myTask
task myTask { configure closure }  // closure是一個(gè)閉包
task myType << { task action }    // <<符號是doLast的縮寫  
task myTask(type: SomeType)   // SomeType可以指定任務(wù)類型,Gradle本身提供有Copy、Delete、Sync等
task myTask(type: SomeType) { configure closure }

Task的API文檔:

https://docs.gradle.org/current/dsl/org.gradle.api.Task.html

自定義Task

在Gradle中,我們有3種方法可以自定義Task时迫。

(1)在build.gradle文件中定義

Gradle使用的是Groovy代碼纸肉,所以在build.gradle文件中姐刁,我們便可以定義Task類谬俄。

// 需要繼承自DefaultTask
class HelloWorldTask extends DefaultTask {
    // @Optional 表示在配置該Task時(shí)宿礁,message是可選的控汉。
    @Optional
    String message = 'I am kaku'
    // @TaskAction 表示該Task要執(zhí)行的動(dòng)作,即在調(diào)用該Task時(shí),hello()方法將被執(zhí)行
    @TaskAction
    def hello(){
        println "hello world $message"
    }
}

// hello使用了默認(rèn)的message值
task hello(type:HelloWorldTask)

// 重新設(shè)置了message的值
task helloOne(type:HelloWorldTask){
   message ="I am a android developer"
}

(2)在當(dāng)前工程中定義

當(dāng)項(xiàng)目中自定義Task類型比較多時(shí)沐旨,可以將自定義Task寫在buildSrc項(xiàng)目中。
具體做法為:在項(xiàng)目的根目錄下新建一個(gè)名為buildSrc文件夾,然后依次新建子目錄src/main/groovy,然后可以建自己的包名烟央,這里以demo.gradle.task為例钞艇,依次新建子目錄demo/gradle/task,然后在buildSrc根目錄下新建build.gradle文件,里面寫入:

apply plugin: 'groovy'

 dependencies {
    compile gradleApi()
    compile localGroovy()
}

接著在demo.gradle.task包下移怯,創(chuàng)建HelloWorldTask.groovy文件香璃,將(1)中的HelloWorldTask部分代碼粘貼過來

import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction

class HelloWorldTask extends DefaultTask {
    @Optional
    String message = 'I am kaku'

    @TaskAction
    def hello() {
        println "hello world $message"
    }
}

最終目錄結(jié)構(gòu)如下:

image.png

(3)在單獨(dú)的項(xiàng)目中定義

當(dāng)自定義的Task需要能夠提供給其他項(xiàng)目中使用時(shí),可以通過聲明依賴的方式引入Task舟误。
具體做法為: 創(chuàng)建一個(gè)項(xiàng)目葡秒,將(2)中的buildSrc目錄下的內(nèi)容copy到新建項(xiàng)目中,然后將該項(xiàng)目生成的jar文件上傳到repository中嵌溢。

build.gradle如下:

apply plugin: 'groovy'
apply plugin: 'maven'
version = '1.0'
group = 'skr'
archivesBaseName = 'hellotask'

repositories.mavenCentral()

dependencies {
    compile gradleApi()
    compile localGroovy()
}

uploadArchives {
    repositories.mavenDeployer {
        repository(url: 'file:../lib')
    }
}

執(zhí)行 gradlew uploadArchives 眯牧,所生成的jar文件將被上傳到上級目錄的lib(../lib)文件夾中

在使用該HelloWorldTask時(shí),客戶端的build.gradle文件需要做以下配置:

buildscript {
    repositories {
        maven {
            url 'file:../lib'
        }

    }

    dependencies {
        classpath group: 'skr', name: 'hellotask', version: '1.0'
    }
}


task hello(type: HelloWorldTask)

自定義Plugin

與自定義Task相似赖草,也是3種定義方式学少,只是代碼不一樣:

apply plugin: DateAndTimePlugin

dateAndTime {
    timeFormat = 'HH:mm:ss.SSS'
    dateFormat = 'MM/dd/yyyy'
}

// 每一個(gè)自定義的Plugin都需要實(shí)現(xiàn)Plugin<T>接口
class DateAndTimePlugin implements Plugin<Project> {
    //該接口定義了一個(gè)apply()方法,在該方法中秧骑,我們可以操作Project版确,
    //比如向其中加入Task,定義額外的Property等乎折。
    void apply(Project project) {
        project.extensions.create("dateAndTime", DateAndTimePluginExtension)
        //每個(gè)Gradle的Project都維護(hù)了一個(gè)ExtenionContainer绒疗,
        //我們可以通過project.extentions進(jìn)行訪問
        //比如讀取額外的Property和定義額外的Property等。
        project.task('showTime') << {
            println "Current time is " + new Date().format(project.dateAndTime.timeFormat)
        }

        project.tasks.create('showDate') << {
            println "Current date is " + new Date().format(project.dateAndTime.dateFormat)
        }
    }
}

//向Project中定義了一個(gè)名為dateAndTime的extension
//并向其中加入了2個(gè)Property骂澄,分別為timeFormat和dateFormat
class DateAndTimePluginExtension {
    String timeFormat = "MM/dd/yyyyHH:mm:ss.SSS"
    String dateFormat = "yyyy-MM-dd"
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吓蘑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坟冲,更是在濱河造成了極大的恐慌磨镶,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件健提,死亡現(xiàn)場離奇詭異琳猫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)私痹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門沸移,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痪伦,“玉大人,你說我怎么就攤上這事雹锣⊥矗” “怎么了?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵蕊爵,是天一觀的道長辉哥。 經(jīng)常有香客問我,道長攒射,這世上最難降的妖魔是什么醋旦? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮会放,結(jié)果婚禮上饲齐,老公的妹妹穿的比我還像新娘。我一直安慰自己咧最,他們只是感情好捂人,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著矢沿,像睡著了一般滥搭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捣鲸,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天瑟匆,我揣著相機(jī)與錄音,去河邊找鬼栽惶。 笑死愁溜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的外厂。 我是一名探鬼主播祝谚,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼酣衷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起次泽,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤穿仪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后意荤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啊片,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年玖像,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了紫谷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖笤昨,靈堂內(nèi)的尸體忽然破棺而出祖驱,到底是詐尸還是另有隱情,我是刑警寧澤瞒窒,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布捺僻,位于F島的核電站,受9級特大地震影響崇裁,放射性物質(zhì)發(fā)生泄漏匕坯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一拔稳、第九天 我趴在偏房一處隱蔽的房頂上張望葛峻。 院中可真熱鬧,春花似錦巴比、人聲如沸迄薄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至植旧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間野蝇,已是汗流浹背谁尸。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留稼病,地道東北人选侨。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像然走,于是被迫代替她去往敵國和親援制。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容