Gradle 插件

Android Gradle 插件 (AGP) 是官方的 Android 應(yīng)用構(gòu)建系統(tǒng)。它支持編譯許多不同類型的源代碼吴菠,以及將其鏈接到可在實體 Android 設(shè)備或模擬器上運行的應(yīng)用中橄教。AGP 包含插件擴展點清寇,用于控制 build 輸入并通過可與標準 build 任務(wù)集成的新步驟擴展其功能。

Gradle build 基礎(chǔ)知識

本指南未涵蓋整個 Gradle 構(gòu)建系統(tǒng)护蝶。不過华烟,它涵蓋了與我們的 API 集成所需的最基本的概念。該指南還鏈接到了主 Gradle 文檔持灰,以便您進一步了解相關(guān)信息盔夜。

我們假定您對 Gradle 的工作原理已有基本了解,包括如何配置項目、修改 build 文件喂链、應(yīng)用插件以及運行任務(wù)返十。如需了解關(guān)于 AGP 的 Gradle 基礎(chǔ)知識,我們建議您查看配置 build椭微。如需了解用于自定義 Gradle 插件的通用框架洞坑,請參閱開發(fā)自定義 Gradle 插件

Gradle 延遲類型術(shù)語表

Gradle 提供多種類型蝇率,它們可表現(xiàn)出“延遲”行為检诗,或者幫助將繁重的計算或 Task 創(chuàng)建推遲到 build 的后續(xù)階段。這些類型是許多 Gradle 和 AGP API 的核心瓢剿。以下列表包含延遲執(zhí)行涉及的主要 Gradle 類型及其主要方法。

<dl style="box-sizing: inherit; margin: 0px; padding: 0px; color: rgb(32, 33, 36); font-family: "Google Sans Text", "Noto Sans", "Noto Sans JP", "Noto Sans KR", "Noto Naskh Arabic", "Noto Sans Thai", "Noto Sans Hebrew", "Noto Sans Bengali", sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">

<dt style="box-sizing: inherit; font: 700 16px/24px var(--devsite-primary-font-family); margin: 16px 0px;">Provider<T></dt>

<dd style="box-sizing: inherit; margin: 16px 0px; padding: 0px 0px 0px 40px;">提供類型為 T 的值(其中“T”表示任意類型)悠轩,該值可以在執(zhí)行階段使用 get() 讀取间狂,也可以使用 map()flatMap()zip() 方法轉(zhuǎn)換為新的 Provider<S>(其中“S”表示其他類型)火架。請注意鉴象,切勿在配置階段調(diào)用 get()

  • map():接受 lambda 并生成類型為 SProvider何鸡,即 Provider<S>纺弊。map() 的 lambda 參數(shù)會采用值 T 并生成值 S。系統(tǒng)不會立即執(zhí)行 lambda骡男,而是會推遲到在生成的 Provider<S> 上調(diào)用 get() 時執(zhí)行淆游,從而讓整個鏈條變得延遲。
  • flatMap():同樣會接受 lambda 并生成 Provider<S>隔盛,但 lambda 會采用值 T 并生成 Provider<S>(而不是直接生成值 S)犹菱。如果在配置時無法確定 S 且您只能獲得 Provider<S>,請使用 flatMap()吮炕。實際上腊脱,如果您使用了 map() 并且最終生成的類型為 Provider<Provider<S>>,則可能表示您本該使用 flatMap()龙亲。
  • zip():可讓您結(jié)合兩個 Provider 實例以生成新的 Provider陕凹,其值是使用將兩個輸入 Providers 實例的值結(jié)合的函數(shù)計算得出的。

</dd>

<dt style="box-sizing: inherit; font: 700 16px/24px var(--devsite-primary-font-family); margin: 16px 0px;">Property<T></dt>

<dd style="box-sizing: inherit; margin: 16px 0px; padding: 0px 0px 0px 40px;">實現(xiàn) Provider<T>鳄炉,這樣會提供類型為 T 的值杜耙。與只讀的 Provider<T> 不同,您還可以為 Property<T> 設(shè)置值拂盯。為其設(shè)置值的方法有兩種:

  • 在可行的情況下直接設(shè)置類型為 T 的值泥技,而無需推遲計算。
  • 將另一個 Provider<T> 設(shè)置為 Property<T> 的值的來源。在這種情況下珊豹,值 T 只會在系統(tǒng)調(diào)用 Property.get() 時具體化簸呈。

</dd>

<dt style="box-sizing: inherit; font: 700 16px/24px var(--devsite-primary-font-family); margin: 16px 0px;">TaskProvider</dt>

<dd style="box-sizing: inherit; margin: 16px 0px; padding: 0px 0px 0px 40px;">實現(xiàn) Provider<Task>。如需生成 TaskProvider店茶,請使用 tasks.register()蜕便,而不是 tasks.create(),以確保任務(wù)只在需要時才會延遲實例化贩幻。在 Task 創(chuàng)建之前轿腺,您可以使用 flatMap() 來訪問該 Task 的輸出,如果您想將此輸出用作其他 Task 實例的輸入丛楚,這會很實用族壳。</dd>

</dl>

如要以延遲方式設(shè)置任務(wù)的輸入和輸出,提供程序及其轉(zhuǎn)換方法至關(guān)重要趣些,也就是說仿荆,無需預(yù)先創(chuàng)建所有任務(wù)并解析值。

提供程序還攜帶有任務(wù)依賴項信息坏平。當您通過轉(zhuǎn)換一個 Task 的輸出來創(chuàng)建 Provider 時拢操,該 Task 會成為相應(yīng) Provider 的隱式依賴項,無論 Provider 的值在何時進行解析(例如當另一個 Task 需要它時)舶替,系統(tǒng)都要會創(chuàng)建并運行該 Task令境。

下面的示例展示了如何注冊 GitVersionTaskManifestProducerTask 這兩個任務(wù),同時將 Task 實例的創(chuàng)建推遲到實際需要時顾瞪。ManifestProducerTask 輸入值設(shè)置成了從 GitVersionTask 的輸出獲取的 Provider舔庶,因此 ManifestProducerTask 隱式依賴于 GitVersionTask

// Register a task lazily to get its TaskProvider.
val gitVersionProvider: TaskProvider =
    project.tasks.register("gitVersionProvider", GitVersionTask::class.java) {
        it.gitVersionOutputFile.set(
            File(project.buildDir, "intermediates/gitVersionProvider/output")
        )
    }

...

/**
 * Register another task in the configuration block (also executed lazily,
 * only if the task is required).
 */
val manifestProducer =
    project.tasks.register(variant.name + "ManifestProducer", ManifestProducerTask::class.java) {
        /**
         * Connect this task's input (gitInfoFile) to the output of
         * gitVersionProvider.
         */
        it.gitInfoFile.set(gitVersionProvider.flatMap(GitVersionTask::gitVersionOutputFile))
    }

這兩個任務(wù)只會在被明確請求時才會執(zhí)行陈醒。這種請求會發(fā)生在 Gradle 調(diào)用的過程中栖茉,例如,當您運行 ./gradlew debugManifestProducer 時孵延,或者當您將 ManifestProducerTask 的輸出關(guān)聯(lián)到其他某些任務(wù)并且必須使用其值時吕漂。

盡管您將編寫會使用輸入和/或生成輸出的自定義任務(wù),但 AGP 不直接提供對其任務(wù)的公開訪問權(quán)限尘应。這些權(quán)限屬于實現(xiàn)細節(jié)惶凝,每個版本都不一樣。不過犬钢,AGP 會提供 Variant API 及對其任務(wù)輸出的訪問權(quán)限苍鲜,或者提供可供您讀取和轉(zhuǎn)換的 build 工件。如需了解詳情玷犹,請參閱本文檔的 Variant API混滔、工件和任務(wù)部分。

Gradle build 階段

項目構(gòu)建本身是一個復(fù)雜且耗費資源的過程,并且涉及各種功能坯屿,例如任務(wù)配置規(guī)避油湖、更新檢查和配置緩存功能,這些功能有助于最大程度減少花在可重現(xiàn)或非必要計算上的時間领跛。

若要應(yīng)用其中某些優(yōu)化功能乏德,Gradle 腳本和插件在以下每個不同的 Gradle build 階段都必須遵循嚴格的規(guī)則:初始化、配置和執(zhí)行吠昭。在本指南中喊括,我們將重點介紹配置階段和執(zhí)行階段。如需詳細了解所有階段矢棚,請參閱 Gradle build 生命周期指南郑什。

配置階段

在配置階段,系統(tǒng)會評估 build 涉及到的所有項目的 build 腳本蒲肋、應(yīng)用插件并解析 build 依賴項蘑拯。此階段應(yīng)該用來使用 DSL 對象配置 build,以及以延遲方式注冊任務(wù)及其輸入肉津。

由于配置階段總是在運行,因此無論系統(tǒng)請求運行哪個任務(wù)舱沧,都務(wù)必讓該階段保持精簡妹沙,并對所有計算進行限制,防止其依賴于輸入而不是 build 腳本本身熟吏。也就是說距糖,您不應(yīng)執(zhí)行外部程序或從網(wǎng)絡(luò)中讀取內(nèi)容,也不應(yīng)執(zhí)行可以作為合適的 Task 實例推遲到執(zhí)行階段的長時間計算牵寺。

注意:使用即將推出的配置緩存功能悍引,此階段的結(jié)果將被緩存,以供后續(xù)運行帽氓,但前提是要特別注意讓構(gòu)建系統(tǒng)知道所有動態(tài)輸入趣斤,例如文件讀取或?qū)Νh(huán)境變量的訪問。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末黎休,一起剝皮案震驚了整個濱河市浓领,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌势腮,老刑警劉巖联贩,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捎拯,居然都是意外死亡泪幌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祸泪,“玉大人吗浩,你說我怎么就攤上這事≡〉危” “怎么了拓萌?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長升略。 經(jīng)常有香客問我微王,道長,這世上最難降的妖魔是什么品嚣? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任炕倘,我火速辦了婚禮,結(jié)果婚禮上翰撑,老公的妹妹穿的比我還像新娘罩旋。我一直安慰自己,他們只是感情好眶诈,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布涨醋。 她就那樣靜靜地躺著,像睡著了一般逝撬。 火紅的嫁衣襯著肌膚如雪浴骂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天宪潮,我揣著相機與錄音溯警,去河邊找鬼。 笑死狡相,一個胖子當著我的面吹牛梯轻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播尽棕,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼喳挑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了滔悉?” 一聲冷哼從身側(cè)響起蟀悦,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎氧敢,沒想到半個月后日戈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡孙乖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年浙炼,在試婚紗的時候發(fā)現(xiàn)自己被綠了份氧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡弯屈,死狀恐怖蜗帜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情资厉,我是刑警寧澤厅缺,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站宴偿,受9級特大地震影響湘捎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜窄刘,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一窥妇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸辱魁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至吨岭,卻和暖如春拉宗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背未妹。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工簿废, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留空入,地道東北人络它。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像歪赢,于是被迫代替她去往敵國和親化戳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

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