Gradle構(gòu)建生命周期簡介和通用Maven打包腳本

Gradle構(gòu)建生命周期簡介和通用Maven打包腳本

Gradle構(gòu)建生命周期

Gradle構(gòu)建過程分為三個大的步驟:初始化昆淡、配置和執(zhí)行昂灵。

初始化

初始化階段的任務是根據(jù)settings.gradle創(chuàng)建項目的層次結(jié)構(gòu),為每一個module創(chuàng)建一個Project實例管削。并且在初始化之前會構(gòu)造一個Settings對象撑螺,主要包含以下方法,可以直接在settings.gradle中訪問甘晤。

- findProject(File): ProjectDescriptor
- findProject(String): ProjectDescriptor
- getGradle(): Gradle
- getRootDir():File
- getRootProject(): ProjectDescriptor
- getSettings(): Settings
- project(File): ProjectDescriptor
- project(String): ProjectDescriptor

比如可以通過如下代碼向Gradle的構(gòu)建過程添加監(jiān)聽:

gradle.addBuildListener(new BuildListener() {
  void buildStarted(Gradle var1) {
    println '開始構(gòu)建'
  }
  void settingsEvaluated(Settings var1) {
    println 'settings評估完成(settins.gradle中代碼執(zhí)行完畢)'
    // var1.gradle.rootProject 這里訪問Project對象時會報錯线婚,還未完成Project的初始化
  }
  void projectsLoaded(Gradle var1) {
    println '項目結(jié)構(gòu)加載完成(初始化階段結(jié)束)'
    println '初始化結(jié)束,可訪問根項目:' + var1.gradle.rootProject
  }
  void projectsEvaluated(Gradle var1) {
    println '所有項目評估完成(配置階段結(jié)束)'
  }
  void buildFinished(BuildResult var1) {
    println '構(gòu)建結(jié)束 '
  }
})

執(zhí)行結(jié)果如下:

settings評估完成(settins.gradle中代碼執(zhí)行完畢)
項目結(jié)構(gòu)加載完成(初始化階段結(jié)束)
初始化結(jié)束漱逸,可訪問根項目:root project 'GradleTest'
所有項目評估完成(配置階段結(jié)束)
:buildEnvironment

------------------------------------------------------------
Root project
------------------------------------------------------------

classpath
No dependencies

BUILD SUCCESSFUL

Total time: 0.959 secs
構(gòu)建結(jié)束 

配置

配置階段的任務是執(zhí)行各項目下的build.gradle腳本虹脯,完成Project的配置奏候,并且構(gòu)造Task任務依賴關(guān)系圖以便在執(zhí)行階段按照依賴關(guān)系執(zhí)行Task。該階段也是我們最常接觸到的構(gòu)建階段咒彤,比如應用外部構(gòu)建插件apply plugin: 'com.android.application'咒精,配置插件的屬性android{...}等。每個build.gralde腳本文件對應一個Project對象歇拆,在初始化階段創(chuàng)建,Project的接口文檔厂庇。配置階段執(zhí)行的代碼包括build.gralde中的各種語句输吏、閉包以及Task中的配置段語句。

println 'build.gradle的配置階段'

// 調(diào)用Project的dependencies(Closure c)聲明項目依賴
dependencies {
    // 閉包中執(zhí)行的代碼
    println 'dependencies中執(zhí)行的代碼'
}

// 創(chuàng)建一個Task
task test() {
  println 'Task中的配置代碼'
  // 定義一個閉包
  def a = {
    println 'Task中的配置代碼2'
  }
  // 執(zhí)行閉包
  a()
  doFirst {
    println '這段代碼配置階段不執(zhí)行'
  }
}

println '我是順序執(zhí)行的'

調(diào)用gradle build拄氯,得到如下結(jié)果:

build.gradle的配置階段
dependencies中執(zhí)行的代碼
Task中的配置代碼
Task中的配置代碼2
我是順序執(zhí)行的
:buildEnvironment

------------------------------------------------------------
Root project
------------------------------------------------------------

classpath
No dependencies

BUILD SUCCESSFUL

Total time: 1.144 secs

一定要注意它浅,配置階段不僅執(zhí)行build.gradle中的語句姐霍,還包括了Task中的配置語句。**從上面執(zhí)行結(jié)果中可以看到邮弹,在執(zhí)行了dependencies的閉包后腌乡,直接執(zhí)行的是任務test中的配置段代碼(Task中除了Action外的代碼段都在配置階段執(zhí)行)夜牡。
另外一點,無論執(zhí)行Gradle的任何命令急迂,初始化階段和配置階段的代碼都會被執(zhí)行蹦肴。
同樣是上面那段Gradle腳本,我們執(zhí)行幫助任務gradle help勺阐,任然會打印出上面的執(zhí)行結(jié)果矛双。我們在排查構(gòu)建速度問題的時候可以留意,是否部分代碼可以寫成任務Task懒闷,從而減少配置階段消耗的時間。

執(zhí)行

在配置階段結(jié)束后愤估,Gradle會根據(jù)任務Task的依賴關(guān)系創(chuàng)建一個有向無環(huán)圖,可以通過Gradle對象的getTaskGraph方法訪問织阅,對應的類為TaskExecutionGraph震捣,然后通過調(diào)用gradle <任務名>執(zhí)行對應任務蒿赢。

通用Maven打包上傳腳本

通常我們在開發(fā)中遇到的情況是lib模塊開發(fā)階段和需要打包階段的腳本配置方面有很大差別,所以一般的做法多為開發(fā)階段的lib模塊在需要上傳到Maven倉庫的時候羡棵,會有另外一個專用的項目來打包目標模塊和上傳皂冰,這個專用的模塊一般情況下是一個殼子,而且可能因為lib模塊在改動manifest文件或者BuildConfig參數(shù)的時候赂蕴,需要對應要做出修改

但是這樣做舶胀,往往意味著修改起來很麻煩,而且容易忘走贪。所以我們需要一個通用的打包腳本來處理這些情況。

所以思路就是不使用殼module,直接使用開發(fā)的lib模塊上傳到maven庫嗤瞎。而且考慮到歷史原因及其兼容啸盏,不能直接在lib模塊修改耿导,那么就只能在rootProject這個層級考慮做一些事情。

上面有講到Gradle在各個階段的任務醋火,同時,Gradle也提供了非常多的鉤子給開發(fā)者自定義構(gòu)建行為

gradle_hook.png

由此可以看到柿冲,我們的目標很明確假抄,就是在lib模塊配置階段為我們注入一些我們需要的操作:移除開發(fā)階段的本地依賴丽猬、移除maven配置文件的本地依賴、添加本地依賴的maven版本依賴谬以。

//跟項目.gradle
allprojects {
    repositories {
        jcenter()
        google()
        afterEvaluate { project ->
            if (project.name == 'gisdk') {
                println '依賴maven插件:apply plugin maven for ' + project
                project.apply from: "${rootProject.projectDir}/maven.gradle"
                println "取消發(fā)布時debug版本的編譯"
                project.android.publishNonDefault false
                project.dependencies {
                    println '依賴現(xiàn)網(wǎng)模塊'
                    compile "xxx.xxx:xxx:${version}"
                }
                project.configurations {
                    println '排除本地依賴'
                    all*.exclude group: '${root_project_name}'
                }
                project.tasks.create(name: 'deleteKeepProguardRules') {
                    doFirst {
                        def path = "${project.projectDir}/build/intermediates/exploded-aar/com.xxx/xxx/${rootProject.ext.gtc.version}/proguard.txt"
                        def bFile = new File(path)
                        if (bFile.exists()) {
                            bFile.delete()
                            println '刪除keep文件成功'
                        } else {
                            println '文件不存在:' + path
                        }
                    }
                }
                project.tasks.whenTaskAdded { task ->
                    if (task.name == 'transformClassesAndResourcesWithProguardForRelease') {
                        task.dependsOn deleteKeepProguardRules
                    }
                }
            }
        }
    }

}
//maven.gradle

apply plugin: 'maven'

def mavenProps = rootProject.ext.maven // 配置

def getProjectVersion() {
    def sdkProps = rootProject.ext.sdk // 配置
    return sdkProps.version
}

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: mavenProps.url) {
                authentication(userName: mavenProps.userName, password: mavenProps.pwd)
            }

            pom.groupId = mavenProps.groupId
            pom.artifactId = project.name
            pom.version = getProjectVersion() + mavenProps.snapshot
            println '上傳的包:' + "${pom.groupId}:${pom.artifactId}:${pom.version}"

            pom.whenConfigured { pom ->
                def dependencies = []
                pom.dependencies.each { dep ->
                    if (dep.version == 'unspecified') {
                        println "無效的依賴:${dep.groupId}:${dep.artifactId}:${dep.version}"
                    } else {
                        dependencies.add(dep)
                    }
                }
                pom.dependencies = dependencies
                pom.dependencies.each { dep ->
                    println "最終的依賴:${dep.groupId}:${dep.artifactId}:${dep.version}"
                }
            }
        }
    }
}

至此,lib模塊就可以實現(xiàn)無侵入式的maven打包上傳能力

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末铭乾,一起剝皮案震驚了整個濱河市娃循,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捧书,老刑警劉巖骤星,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洞难,死亡現(xiàn)場離奇詭異揭朝,居然都是意外死亡,警方通過查閱死者的電腦和手機柱嫌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門编丘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嘉抓,你說我怎么就攤上這事抑片÷逊穑” “怎么了敞斋?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵渺尘,是天一觀的道長。 經(jīng)常有香客問我丢郊,道長医咨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮很泊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘戳鹅。我一直安慰自己昏兆,他們只是感情好,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布爬虱。 她就那樣靜靜地躺著隶债,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跑筝。 梳的紋絲不亂的頭發(fā)上死讹,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音曲梗,去河邊找鬼赞警。 笑死逛腿,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的仅颇。 我是一名探鬼主播单默,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼搁廓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起耕皮,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤境蜕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后凌停,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粱年,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年罚拟,在試婚紗的時候發(fā)現(xiàn)自己被綠了台诗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡赐俗,死狀恐怖拉队,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阻逮,我是刑警寧澤粱快,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站叔扼,受9級特大地震影響事哭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瓜富,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一鳍咱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧食呻,春花似錦流炕、人聲如沸澎现。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剑辫。三九已至干旧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妹蔽,已是汗流浹背椎眯。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工挠将, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人编整。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓舔稀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親掌测。 傳聞我的和親對象是個殘疾皇子内贮,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

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

  • 爸媽去井岡山了,一路平安汞斧。 家里莫名冷清好多夜郁,明明不是我家啊。
    二八蝸牛閱讀 153評論 0 2
  • 學習過笑來老師《財富自由之路》專欄的同學應該都知道這幾個道理: 注意力>時間>金錢 付費就是撿便宜 可是知道了粘勒,并...
    淼淋閱讀 276評論 0 2
  • 一竞端、搭建Maven私服,使用Nexus搭建1庙睡、下載Nexus,點擊nexus下載事富,下載nexus-2.13.0-0...
    SuperKune閱讀 693評論 0 5