您好,登錄后才能下訂單哦!
今天小編給大家分享一下Gradle Build Cache引發(fā)的Task緩存編譯問(wèn)題怎么解決的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。
Gradle 構(gòu)建緩存是一種緩存機(jī)制,旨在通過(guò)重用其他構(gòu)建產(chǎn)生的輸出來(lái)節(jié)省時(shí)間。構(gòu)建緩存通過(guò)存儲(chǔ)(本地或遠(yuǎn)程)構(gòu)建輸出并允許構(gòu)建在確定輸入沒(méi)有更改時(shí)從緩存中獲取這些輸出來(lái)工作,從而避免了重新生成它們的昂貴工作。
使用構(gòu)建緩存的第一個(gè)功能是任務(wù)輸出緩存。本質(zhì)上,任務(wù)輸出緩存利用了與最新檢查相同的智能,當(dāng)先前的本地構(gòu)建已經(jīng)產(chǎn)生一組任務(wù)輸出時(shí),Gradle 使用它來(lái)避免工作。但是,任務(wù)輸出緩存不僅限于同一工作區(qū)中的先前構(gòu)建,而是允許 Gradle 重用本地機(jī)器上任何位置的任何早期構(gòu)建的任務(wù)輸出。當(dāng)使用共享構(gòu)建緩存進(jìn)行任務(wù)輸出緩存時(shí),這甚至可以跨開(kāi)發(fā)人員機(jī)器和構(gòu)建代理工作。
除了任務(wù)之外,工件轉(zhuǎn)換還可以利用構(gòu)建緩存并重用其輸出,類(lèi)似于任務(wù)輸出緩存。
以上內(nèi)容摘自gradle官方文檔,鏈接如下
我簡(jiǎn)單的翻譯下給各位大佬,在本地存在build cache的情況下,gradle task會(huì)基于當(dāng)前的輸入來(lái)作為緩存的key值,如果輸入內(nèi)容沒(méi)有發(fā)生變更,則意味著本Task可以被跳過(guò),另外這個(gè)不同于增量編譯。
又可以偷下官方的圖片了。舉個(gè)栗子,JavaCompiler task
的輸入的java文件和上一次編譯的一樣,則意味著該任務(wù)可以使用原來(lái)編譯輸出作為編譯產(chǎn)物。
任務(wù)類(lèi)型需要使用 @CacheableTask 注釋選擇加入任務(wù)輸出緩存。 請(qǐng)注意,@CacheableTask 不被子類(lèi)繼承。 默認(rèn)情況下,自定義任務(wù)類(lèi)型不可緩存。
官方有說(shuō)明什么情況下會(huì)使用編譯緩存,首先我們的Task
要被定義成@CacheableTask
。
另外對(duì)于Task內(nèi)部的輸入和輸出也需要打上@TaskInputs
和@TaskOutputs
注解。這樣才能保證當(dāng)前的Task具備了編譯緩存的能力。
所以想要寫(xiě)一個(gè)能具備緩存能力的Task也是比較復(fù)雜的。這也就是為什么Android后面會(huì)開(kāi)始推動(dòng)Artifacts
的使用了,讓開(kāi)發(fā)盡量可以少關(guān)心輸入輸出相關(guān)的邏輯。
我們升級(jí)適配完AGP 7.0 | 雜談
那么相對(duì)的,沒(méi)有定義@CacheableTask
的則認(rèn)為是內(nèi)有編譯緩存的任務(wù)。
在上述這種被跳過(guò)的任務(wù)哦,一般都會(huì)有在Task編譯完成之后帶上一些特殊的標(biāo)識(shí)符。
(no label) or EXECUTED
任務(wù)正常執(zhí)行了。
UP-TO-DATE
任務(wù)輸出沒(méi)有變更。
輸入輸出均沒(méi)有發(fā)生變更。
任務(wù)執(zhí)行了,但是任務(wù)告訴gradle輸出并未發(fā)生變更。
任務(wù)沒(méi)有執(zhí)行和一些依賴項(xiàng),但所有依賴項(xiàng)都是最新的、已跳過(guò)或來(lái)自緩存。
任務(wù)沒(méi)有執(zhí)行也沒(méi)有依賴。
FROM-CACHE
任務(wù)的輸出可以從之前的執(zhí)行中找到。任務(wù)已從構(gòu)建緩存恢復(fù)輸出。
SKIPPED
該任務(wù)沒(méi)有被執(zhí)行。任務(wù)已明確從命令行中排除。
NO-SOURCE
當(dāng)前無(wú)需執(zhí)行該任務(wù)。輸入內(nèi)容并沒(méi)有源文件,比如.java
簡(jiǎn)單的來(lái)說(shuō),除了第一種情況以外,其他的都是任務(wù)被跳過(guò)。
好了,有了前置的知識(shí)儲(chǔ)備的情況下,我們就可以展開(kāi)說(shuō)一下我們最近碰到的一個(gè)奇怪的問(wèn)題了。
我們有個(gè)protobuf
編譯的倉(cāng)庫(kù),專(zhuān)門(mén)負(fù)責(zé)將pb文件轉(zhuǎn)化成java或者kotlin。然后會(huì)把這些生成的文件移動(dòng)到另外兩個(gè)模塊進(jìn)行打包,最后刪除生成的所有類(lèi)文件。然后再去執(zhí)行javacompiler task。
這個(gè)模塊出現(xiàn)了一個(gè)二次編譯的問(wèn)題。第一次打包protobuf
模塊的時(shí)候編譯是正常的,然后當(dāng)二次編譯該模塊的情況下,該模塊就會(huì)出現(xiàn)類(lèi)丟失的問(wèn)題。
這個(gè)問(wèn)題分析起來(lái)就比較簡(jiǎn)單。在二次編譯的情況下呢,因?yàn)檩斎氲膬?nèi)容并沒(méi)有發(fā)生變更,所以觸發(fā)了Gradle Task
相關(guān)的緩存,然后所有的pb文件轉(zhuǎn)化成java kt的過(guò)程就被跳過(guò)了。但是呢后續(xù)的copy task因?yàn)楸旧聿痪邆渚彺婺芰?,所以他還是會(huì)執(zhí)行一次cv的任務(wù)。但是原來(lái)生成的java和kt已經(jīng)被刪除了。這個(gè)時(shí)候他就會(huì)把空的文件夾進(jìn)行一次覆蓋操作。之后就導(dǎo)致了原來(lái)的java和kt文件全部丟失的問(wèn)題。
這就是一個(gè)很有趣的build cache
導(dǎo)致的奇形怪狀的問(wèn)題,因?yàn)樯弦粋€(gè)任務(wù)具備了編譯緩存,之后跳過(guò)了編譯直接用了原來(lái)的output輸出。但是呢下一個(gè)任務(wù)非緩存的,所以必然還是會(huì)執(zhí)行拷貝任務(wù)。
以上就是“Gradle Build Cache引發(fā)的Task緩存編譯問(wèn)題怎么解決”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。