本文記錄的是今天在羣裏提到的昨天所踩的一個坑,有關 AndroidStudio 緩存的。java
先說一下背景。
我負責的一個項目,對一個圖表庫有外部依賴。這個圖表庫是我在維護的,因爲新功能在開發中,因此我就使用了 SNAPSHOT 版本發佈到 OJO(oss.jfrog.org) 上。我在項目中剛更新了依賴,突然想到還少幾個 API,因而發佈了 SNAPSHOT 版本。
故事就這樣開始了。android
這時候回到 AndroidStudio 再去 Sync Project with Gradle Files
確定是拉不下來的。衆所周知,Gradle 的緩存策略中,對於 SNAPSHOT 版本默認的緩存週期是 24 小時,也就是從我上次更新以後,24小時內都會使用上次的緩存。程序員
不周知的也不要緊,我在這裏補充說明一下,在 Gradle 用戶指南的依賴管理一章中,有提到 Gradle 對於動態版本和變化模塊的緩存時間默認是 24 小時。
何爲動態版本?你見過的像3.+
這種就是動態版本,它會取檢查到的最高的版本號。又好比latest.integration
,它也是動態版本。
而變化模塊,就是像0.2-SNAPSHOT
這種後面帶SNAPSHOT
的版本了。
這二者的區別就是,前者儘管你代碼中的版本號寫法不變,但實際上它仍然是去取倉庫的最新版本。然後者它在倉庫中的版本號仍是同樣,仍然是xxx-SNAPSHOT
,但實際上這個版本所對應的內容已經變了。緩存
這裏再多說幾句,緩存週期也是能夠修改的,在 Gradle 用戶指南中一樣有詳細說明,就是添加以下配置:服務器
只是這裏我一開始就貪省事,在更新依賴懶得去改。app
既然如此,那怎麼辦?把 ~/.gradle/caches
整個給幹掉?
不不不,那樣過小題大作。其實這個問題我早已遭遇過,而且對於「漢化」過一遍 Gradle 用戶指南的我來講太簡單了。命令行下執行:運維
這裏囉嗦一下,aTD
是項目中一個 Gradle 任務的縮寫,全名是 assembleTestingDebug
,其中 Testing
是項目裏的一個 ProductFlavor
。這並不重要,重點是後面的參數 --refresh-dependencies
,加上這個參數,表示強制刷新依賴。
可是回到 AndroidStudio 寫代碼,發現代碼提示中新的 API 仍是沒有出來。看來是 Android Studio 沒有更新。不過不要緊,這事我也有經驗。點開右邊的 Gradle 面板,找到 androidDependencies
任務,右鍵,Create xxxxx Configuration
,而後在彈出的面板的 Arguments 一欄中輸入前面提到的參數 --refresh-dependencies
,添加完,在運行那裏選擇它執行。
等執行完,按照幾年前的經驗,這時候應該出來了吧?maven
然而,實際上並無。
這時候我突然想起,咱們公司在阿里雲服務器上搭建了一個 maven 私服,去年的時候我在上面配置了對 OJO 的代理,這時候拉取的是私服上的版本,是它沒有更新?
不要緊,解決方法很簡單,刪!
因而我登陸到 nexus 上,找到緩存的這個庫,右鍵,整個版本刪掉。刪了服務器上的以後,還以爲不放心,因而再把 .gradle 裏的緩存給找出來刪掉,我當時應該是這樣子的: 編輯器
使用 nexus 搭建 maven 私服有幾種好處,一是能夠放公司內部的庫;二是配置對其餘 maven 倉庫的代理,當有人去訪問某一個依賴時它就會緩存下來,下次其餘人再訪問同一個依賴的話它就會直接取緩存,對於一些在國內訪問不是很友好的倉庫如 jcenter,能有效減小等待時間。固然若是公司內部局域網部署一個的話,提高效果會更顯著。ide
最後再執行前面步驟。命令行中已經能夠看到從新下載了這個依賴了,而且我也檢查了 .gradle/caches/modules-2
下對應的源碼 jar 包,確實是更新了。
再回到 Android Studio,發現依然沒有更新。
這什麼狀況?
我疑惑了一下,心中一個聲音響起:
啊(這裏應讀四聲)!
這時候我想到了,新版的 Android Studio 爲了提速,多了一層緩存:對於第三方依賴會把它們解壓出來,放到 ~/.gradle/caches/transforms-1
目錄中。
因而繼續:
刪!
而後再構建,讓它從新緩存,這時候應該就能夠了吧。
在 Android Studio 中執行了構建,而後發現它確實從新緩存了。可是——
悲劇就此發展,深坑就此塌陷!
這時候,我發現不單是新加的 API 沒有出來,編輯器裏有關這個庫的代碼全都變紅了!儘管!項目仍是能跑起來!當時的屏幕是這樣的:
不對不對。咋回事?
這時候我又機智地想到,這裏緩存的路徑有包含 hash 做爲名稱的文件夾,更新了以後,hash 值也不一樣了,因此應該是哪裏的索引沒有對應上。因而找啊找,就在 transforms-1/metadata-1.1
中發現了一個叫 results.bin
的文件。再搜一下里面有沒有包含那個庫的內容:
提示是二進制文件。哦,那就加個參數:
結果出來了,果真有。那好,那就再刪!
等等——我這時謹慎了一下,仍是重命名一下好了。因而重命名,而後再執行構建,而後看到這個文件從新生成了,看起來正朝預料中的發展。然而,有關這個庫的引用仍是報錯。
這時候的我陷入了一番沉思,再試其餘方法:
Sync with File System
Sync Project with Gradle Files
File -> Invalidate Caches / Restart
仍是無效。帶着鬱悶,我下班了。
雖然這問題此刻表現得如此頑固,可是最終它仍是被我解決了。
早上一來,我以爲我應該是有點急了,畢竟項目的開發時間由此被我拖多了一天了,可是做爲一名有着一顆運維的心的程序員,本身踩陷的坑不管怎樣也要把它踩平。
因而我開始往其餘緩存方面上考慮,也沒有去想合不合邏輯。我想到了 Gradle 在構建時會對一個任務的輸入作快照,因而找到項目裏的 .gradle/buildOutputCleanup
目錄,刪!
還不行,那就 .gradle/4.4
(當前使用的 Gradle 版本),刪!
還不對,那就整個 .gradle
,刪!
甚至,~/.gradle/caches/transforms-1/
,刪!
依然不對,那就 Android Studio 的配置文件夾,~/.AndroidStudio3.1
,刪!
刪完從新打開 Android Studio 導入配置,這時候發現已經不是以前的問題了,你覺得問題解決了嗎?不!是問題升級了!這時候已經不是那個庫報紅了,而是全部引用第三方庫的地方都報紅了!!!儘管,仍是能夠運行起來!!
百般無奈之下,繼續 google,看到的仍是前面提到的 Invilate Cache 的方法。突然在 Stackoverflow 中看到了一個看起來不是很常見的回答:
退出 Android Studio,刪除全部的 .iml 文件以及 .idea 目錄,打開 Android Studio 從新導入項目。
咦?這方法沒試過。那就試試吧:
而後從新打開 Android Studio,點 Sync with File System
,這時候奇蹟終於出來了,應該說,Android Studio 終於正常了,編輯器不報紅了!
壓抑着心中的萬分激動,有着打破沙鍋問到底精神的我,對此問題仍不放棄思考。
因此,到底是什麼緣由呢?
我看了一下 .iml 文件,沒什麼異常。那就再看.idea 目錄。
結果以下:
原來是在 .idea/libraries 裏會記錄每個第三方庫的 classes, javadoc 以及 sources 所對應的路徑。其中 classes 對應的正是前面所提到的 transforms-1 裏的目錄,一樣也正如前面所說,其中包含的路徑是有 hash 值的,更新了依賴以後,hash 值不一樣,新的緩存路徑也就不一樣了,而這裏仍是用的原來被刪的那個路徑,找不到對應的文件固然編輯器裏就提示 cannot resolve symbol
了。因此正確而直接的解決方案應該是刪除 .idea/libraries/
裏對應該第三方庫的 xml 文件讓它從新生成,或者是直接修改該 xml 文件的內容,改成更新依賴以後的路徑。