DEVLOG 9.22 Gradle 筆記(1)Gradle重要概念掃盲
構(gòu)建生命周期
初始化 - 配置 - 執(zhí)行
初始化階段:
初始化階段Gradle會根據(jù)根目錄下面的settings.gradle構(gòu)建Settings對象,settings.gradle會決定有哪些模塊參與構(gòu)建。構(gòu)建工具會根據(jù)每一個build.gradle構(gòu)建Project對象。根目錄的build
.gradle可以理解為最頂層的Project,每一個模塊中的Project可以通過rootProject訪問根目錄的Project對象。構(gòu)建工具之后會根據(jù)Settings配置Project
配置階段:
配置階段Gradle會分析每一個Project的依賴關(guān)系。
舉華師匣子2.0為例,華師匣子2.0中配置了很多不同的module,這些module的初衷是為了讓業(yè)務(wù)分離,讓開發(fā)者更注重于開發(fā)主要業(yè)務(wù)。如果存在不同的模塊的話,維護(hù)起來會更加方便,但是這個解耦并不完全,因?yàn)槲覀儾]有將不同的功能分成不同的模塊。不同的模塊之前的UI跳轉(zhuǎn)需要使用Arouter實(shí)現(xiàn),我們沒有這樣分,所以也沒有真正的使用Arouter。

執(zhí)行階段:
執(zhí)行階段會執(zhí)行Task。會按照Task的依賴順序執(zhí)行。
Project
build.gradle中使用的函數(shù) DSL塊不外乎都是Project以及它繼承而來的方法。

application build.gradle 和 app build
application層級的build.gradle是最頂級的Project,里面包括了子Project,也就是app的build.gradle。當(dāng)Gradle啟動的時(shí)候,會先啟動settings.gradle,生成Settings對象,然后再按照這個對象的要求配置build.gradle,include的相關(guān)代碼就寫在settings.gradle中。

子Project中定義的Task也可以被頂級Project訪問到。假設(shè)我在app module中定義了這兩個Task(hello 和 subTask)
使用如下命令可以在打印中找到這兩個Task是屬于app的:

每一個build.gradle 都代表著一個project,每個project都有若干個task。Task表示Gradle的一個原子性操作。
Task
Task表示一系列的Action ,因此可以使用doFirst或者doLast向Task中添加Action對象。Action是一個接口,使用的感覺其實(shí)上就是一個閉包
Task的創(chuàng)建
在build.gradle中可以獲取當(dāng)前的Project的實(shí)例,并且可以通過tasks獲取TaskContainer對象,然后就可以將新的Task加入Project
2. Task的依賴
一個Task又通過若干個Action組成。Gradle中原本的Task的執(zhí)行順序是不確定的,可以通過使用dependsOn指定Task的依賴順序。
3. Task和增量構(gòu)建
Gradle會緩存Task每次的運(yùn)行結(jié)果,在下次運(yùn)行時(shí),檢查輸出結(jié)果有無變更,如果沒有變更就回跳過這次運(yùn)行。如果輸入沒有變化輸出也不會發(fā)生變化。

ext命名空間
ext其實(shí)ExtensionAware的一個特殊屬性
我們可以在頂級的build.gradle的同級目錄下定義一個config.build,里面使用ext定義我們?nèi)炙枰母鞣N常量:
但是這個config.gradle,需要在build.gradle中apply:
這實(shí)際上調(diào)用的是PluginAware的方法:
于是我們可以在頂級的build.gradle和app模塊的build.gradle中訪問到:

我們可以使用Extension給一些可以配置的插件傳值,如果不使用managed properties,我們也可以使用這樣的形式:
這里不寫getter和setter也是可以的
managed properties:
Gradle能夠允許用戶聲明一個屬性為抽象的getter或者是一個抽象的屬性,然后Gradle會自動提供這些屬性的實(shí)現(xiàn):https://docs.gradle.org/current/userguide/custom_gradle_types.html#managed_types
Mutable properties:
聲明一個mutable managed property,需要給Property<T>提供一個抽象的getter。這里的T可以是任意的序列化類型或者是一個fully Gradle Managed type。對于這種屬性,一定不可以聲明任何的setter方法。這個東西有點(diǎn)像kotlin自動生成的getter和setter:
這里的@Input和@TaskAction注解都是一個mark的作用。TaskAction表示這個方法會被標(biāo)記成一個action,在Task執(zhí)行時(shí)被運(yùn)行。
這里和上面直接寫一個類然后設(shè)置值的方式好像沒有本質(zhì)上的不同,但是這里的getUri(getter)可以被轉(zhuǎn)化成一個類似于Kotlin中的字段同時(shí)有了getter和setter的功能。
Read-only managed properties
使用只讀的properties需要給Provider<T>加上getter方法,這個方法的實(shí)現(xiàn)中必須給出這個結(jié)果的推導(dǎo)方式:
Read-only managed nested properties
對于一個嵌套類型的傳值。在這種情況下,用戶不需要寫任何的setter,因?yàn)镚radle會自動實(shí)現(xiàn),并且Gradle會將值傳給嵌套類型內(nèi)部的properties。如果當(dāng)前的property被聲明為一個read-only managed nested property,這個property的getter 方法必須是抽象的并且public或者protected可見性,同時(shí)這個getter方法還需要被注解為@Nested:
但是這里我還有點(diǎn)沒有搞明白,這個Resources應(yīng)該如何傳值呢?
Managed Types
managed type是一個抽象類,或者接口。這個類中沒有任何字段,并且這個類中的所有屬性都是被managed(應(yīng)該是指通過Gradle生成的方法處理?)比如我們上面的Resources
Java bean Properties
使用Java Bean風(fēng)格的Property,這種類型中沒有Property<T>和Provider<T>,但是使用了實(shí)現(xiàn)了的getter 和 setter(常用的Java Bean中g(shù)etter setter 都被手寫寫好了)。這種方式在Gradle中是不被提倡的。

Extension
通過Project獲取ExtensionContainer,初始化新的Extension并且存入ExtensionContainer中。
類似于ext,可以直接通過project獲?。?/p>
同樣也可以使用managed properties:
NamedDomainObjectContainer
我們定義的buildTypes就是領(lǐng)域?qū)ο笕萜?。通過指定不同的buildTypes的名稱release 和debug可以設(shè)置不同的參數(shù)。這也是一個extension,所以內(nèi)部的release和debug的配置是BuildType對象通過ExtensionContainer#create構(gòu)建出來的
參考文章:
https://juejin.cn/post/6844903838290296846
https://www.jianshu.com/p/207c9f6f68c2