Gradle?Build?Cache引發(fā)的Task緩存編譯問題
前言
前一陣子公司內(nèi)部卷了一篇文章大家有興趣的可以看下,大概把我們編譯優(yōu)化的原理介紹了下,當(dāng)然其中還有些技術(shù)細(xì)節(jié)相關(guān)的并沒有寫。
基礎(chǔ)知識
Gradle 構(gòu)建緩存是一種緩存機(jī)制,旨在通過重用其他構(gòu)建產(chǎn)生的輸出來節(jié)省時(shí)間。構(gòu)建緩存通過存儲(本地或遠(yuǎn)程)構(gòu)建輸出并允許構(gòu)建在確定輸入沒有更改時(shí)從緩存中獲取這些輸出來工作,從而避免了重新生成它們的昂貴工作。
使用構(gòu)建緩存的第一個(gè)功能是任務(wù)輸出緩存。本質(zhì)上,任務(wù)輸出緩存利用了與最新檢查相同的智能,當(dāng)先前的本地構(gòu)建已經(jīng)產(chǎn)生一組任務(wù)輸出時(shí),Gradle 使用它來避免工作。但是,任務(wù)輸出緩存不僅限于同一工作區(qū)中的先前構(gòu)建,而是允許 Gradle 重用本地機(jī)器上任何位置的任何早期構(gòu)建的任務(wù)輸出。當(dāng)使用共享構(gòu)建緩存進(jìn)行任務(wù)輸出緩存時(shí),這甚至可以跨開發(fā)人員機(jī)器和構(gòu)建代理工作。
除了任務(wù)之外,工件轉(zhuǎn)換還可以利用構(gòu)建緩存并重用其輸出,類似于任務(wù)輸出緩存。
以上內(nèi)容摘自gradle官方文檔,鏈接如下
我簡單的翻譯下給各位大佬,在本地存在build cache的情況下,gradle task會基于當(dāng)前的輸入來作為緩存的key值,如果輸入內(nèi)容沒有發(fā)生變更,則意味著本Task可以被跳過,另外這個(gè)不同于增量編譯。
又可以偷下官方的圖片了。舉個(gè)栗子,JavaCompiler task
的輸入的java文件和上一次編譯的一樣,則意味著該任務(wù)可以使用原來編譯輸出作為編譯產(chǎn)物。
Cacheable tasks
任務(wù)類型需要使用 @CacheableTask 注釋選擇加入任務(wù)輸出緩存。 請注意,@CacheableTask 不被子類繼承。 默認(rèn)情況下,自定義任務(wù)類型不可緩存。
官方有說明什么情況下會使用編譯緩存,首先我們的Task
要被定義成@CacheableTask
。
另外對于Task內(nèi)部的輸入和輸出也需要打上@TaskInputs
和@TaskOutputs
注解。這樣才能保證當(dāng)前的Task具備了編譯緩存的能力。
所以想要寫一個(gè)能具備緩存能力的Task也是比較復(fù)雜的。這也就是為什么Android后面會開始推動(dòng)Artifacts
的使用了,讓開發(fā)盡量可以少關(guān)心輸入輸出相關(guān)的邏輯。
那么相對的,沒有定義@CacheableTask
的則認(rèn)為是內(nèi)有編譯緩存的任務(wù)。
TaskOutput
在上述這種被跳過的任務(wù)哦,一般都會有在Task編譯完成之后帶上一些特殊的標(biāo)識符。
(no label) or EXECUTED
任務(wù)正常執(zhí)行了。UP-TO-DATE
任務(wù)輸出沒有變更。- 輸入輸出均沒有發(fā)生變更。
- 任務(wù)執(zhí)行了,但是任務(wù)告訴gradle輸出并未發(fā)生變更。
- 任務(wù)沒有執(zhí)行和一些依賴項(xiàng),但所有依賴項(xiàng)都是最新的、已跳過或來自緩存。
- 任務(wù)沒有執(zhí)行也沒有依賴。
FROM-CACHE
任務(wù)的輸出可以從之前的執(zhí)行中找到。任務(wù)已從構(gòu)建緩存恢復(fù)輸出。SKIPPED
該任務(wù)沒有被執(zhí)行。任務(wù)已明確從命令行中排除。NO-SOURCE
當(dāng)前無需執(zhí)行該任務(wù)。輸入內(nèi)容并沒有源文件,比如.java
簡單的來說,除了第一種情況以外,其他的都是任務(wù)被跳過。
有趣的編譯問題
好了,有了前置的知識儲備的情況下,我們就可以展開說一下我們最近碰到的一個(gè)奇怪的問題了。
我們有個(gè)protobuf
編譯的倉庫,專門負(fù)責(zé)將pb文件轉(zhuǎn)化成java或者kotlin。然后會把這些生成的文件移動(dòng)到另外兩個(gè)模塊進(jìn)行打包,最后刪除生成的所有類文件。然后再去執(zhí)行javacompiler task。
這個(gè)模塊出現(xiàn)了一個(gè)二次編譯的問題。第一次打包protobuf
模塊的時(shí)候編譯是正常的,然后當(dāng)二次編譯該模塊的情況下,該模塊就會出現(xiàn)類丟失的問題。
問題分析
這個(gè)問題分析起來就比較簡單。在二次編譯的情況下呢,因?yàn)檩斎氲膬?nèi)容并沒有發(fā)生變更,所以觸發(fā)了Gradle Task
相關(guān)的緩存,然后所有的pb文件轉(zhuǎn)化成java kt的過程就被跳過了。但是呢后續(xù)的copy task因?yàn)楸旧聿痪邆渚彺婺芰?,所以他還是會執(zhí)行一次cv的任務(wù)。但是原來生成的java和kt已經(jīng)被刪除了。這個(gè)時(shí)候他就會把空的文件夾進(jìn)行一次覆蓋操作。之后就導(dǎo)致了原來的java和kt文件全部丟失的問題。
這就是一個(gè)很有趣的build cache
導(dǎo)致的奇形怪狀的問題,因?yàn)樯弦粋€(gè)任務(wù)具備了編譯緩存,之后跳過了編譯直接用了原來的output輸出。但是呢下一個(gè)任務(wù)非緩存的,所以必然還是會執(zhí)行拷貝任務(wù)。
至于解決方案我就不寫了,感覺大家應(yīng)該沒啥興趣。
最后
重要的事情再說一遍,前一陣子在公司內(nèi)部卷了一篇文章大家有興趣的可以看下,大概把我們編譯優(yōu)化的原理介紹了下,當(dāng)然其中還有些技術(shù)細(xì)節(jié)相關(guān)的并沒有寫。
http://chabaoo.cn/article/252481.htm
以上就是Gradle Build Cache引發(fā)的Task緩存編譯問題的詳細(xì)內(nèi)容,更多關(guān)于Gradle Build Cache編譯Task緩存的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android 自定義精美界面包含選項(xiàng)菜單 上下文菜單及監(jiān)聽詳解流程
這篇文章主要介紹了一個(gè)Android實(shí)例小項(xiàng)目,它包含了選項(xiàng)菜單、上下文菜單及其對應(yīng)的監(jiān)聽事件,它很小,但這部分功能在Android開發(fā)中很常見,需要的朋友來看看吧2021-11-11微信支付僅能成功調(diào)用一次問題的解決方法(Android)
這篇文章主要介紹了微信支付僅能成功調(diào)用一次問題的解決方法,感興趣的小伙伴們可以參考一下2016-08-08Android在Sqlite3中的應(yīng)用及多線程使用數(shù)據(jù)庫的建議(實(shí)例代碼)
這篇文章主要介紹了Android在Sqlite3中的應(yīng)用及多線程使用數(shù)據(jù)庫的建議,包括編寫數(shù)據(jù)庫具體操作類、增刪改查,通過實(shí)例代碼介紹了在實(shí)際中的應(yīng)用,需要的朋友可以參考下2022-04-04PC版與Android手機(jī)版帶斷點(diǎn)續(xù)傳的多線程下載
這篇文章主要介紹了PC版與Android手機(jī)版帶斷點(diǎn)續(xù)傳的多線程下載的相關(guān)資料,需要的朋友可以參考下2015-10-10Android2.3實(shí)現(xiàn)Android4.0風(fēng)格EditText的方法
這篇文章主要介紹了Android2.3實(shí)現(xiàn)Android4.0風(fēng)格EditText的方法,涉及Android界面布局及控件調(diào)用的相關(guān)技巧,需要的朋友可以參考下2016-03-03在Android環(huán)境下WebView中攔截所有請求并替換URL示例詳解
這篇文章主要介紹了在Android環(huán)境下WebView中攔截所有請求并替換URL示例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07VS Code開發(fā)React-Native及Flutter 開啟無線局域網(wǎng)安卓真機(jī)調(diào)試問題
這篇文章主要介紹了VS Code開發(fā)React-Native,F(xiàn)lutter 開啟無線局域網(wǎng)安卓真機(jī)調(diào)試,需要的朋友可以參考下2020-04-04Android開發(fā)工程中集成mob短信驗(yàn)證碼功能的方法
這篇文章主要介紹了Android開發(fā)工程中集成mob短信驗(yàn)證碼功能的方法,感興趣的小伙伴們可以參考一下2016-05-05一些有效的Android啟動(dòng)優(yōu)化策略分享
在當(dāng)今激烈競爭的移動(dòng)應(yīng)用市場,應(yīng)用的啟動(dòng)速度直接影響著用戶的第一印象和滿意度,Android的啟動(dòng)優(yōu)化是開發(fā)者必須關(guān)注的關(guān)鍵領(lǐng)域,本文將詳細(xì)介紹一些強(qiáng)大有效的Android啟動(dòng)優(yōu)化策略,幫助你優(yōu)化應(yīng)用的啟動(dòng)過程,為用戶創(chuàng)造更出色的體驗(yàn),需要的朋友可以參考下2023-08-08