Android 如何透過Fresco做Bitmap Disk Lru Cache?

JLin
5 min readSep 15, 2022

--

在官網中有提到如何有效的使用Bitmap,當中提到了Memory Cache與Disk Cache,而方法都是使用LRU的方式

LRU是什麼

簡單來講就是,常用的檔案就可以保留比較久,如果不常使用的檔案在cache中就越容易被自動刷掉,釋放

https://developer.android.com/topic/performance/graphics/cache-bitmap

LruCache有在android系統中,使用也很簡單,需告你要的記憶體大小,然後就可以

但當你想要下次打開app的時候,還可以繼續cache呢?

使用DiskCache

https://developer.android.com/topic/performance/graphics/cache-bitmap#disk-cache

官方給了一個範例,不過這邊要說的是,官方的範例並不完整而且過時(AsyncTask),所以要拼湊起來其實很累,解說的也不夠多,更別提DiskLruCache並不再os內,必須自己去抓source code來使用,因此測試了一陣子,想到不要自己發明製造輪胎,就放棄了

找了一會,有發現JakeWharton有將該檔案放在github,並且可以透過dependency的方式導入到你的project中,

不過專案都是9年前的code了,已經非常久,同樣的使用也非常麻煩,並沒有過多的說明文件,於是我又放棄了

想到有一些抓取影像與顯示的套件,是不是它們能有獨立的caching 機制呢?

其他套件

glide or facebook fresco or coil等等?

是可以使用但很多都是為了透過URL載入到imageView使用,但我們僅需要獨立的將Bitmap存入cache或是從cache抓出來使用,研究了一下直到找到一篇文章後發現Fresco 是可以獨立這樣使用的

廢話不多說

可以直接使用這個,記得要自行引入fresco的depedencies

最簡單的方式就是

putCache(key,bitmap)

取得

readFromCacheSync(key): Bitmap

就這樣,值得一提的是當中有一個

fun readFromStagingArea(cacheKey: SimpleCacheKey): InputStream? {
val stagingArea = StagingArea.getInstance()
val encodedImage = stagingArea[cacheKey]
return encodedImage?.inputStream
}

StagingAres,其實也就是暫存區,我理解應該是類似memory cahce ,在sample中他也會自己先去memory找,如果有就直接回傳,如果沒有就會從disk中抓取

如此就可以很簡單的使用,目前看起來是ok,如果有什麼問題我再來更新此文章。

參考資料

--

--

JLin
JLin

Written by JLin

台中 / JAVA / Android /Kotlin / Kotlin Native 對於Kotlin衍生的JVM等技術 Compose for web / desktop / Ktor Server,生成式AI (Gemini/OpenAI)各式應用, 都有小興趣

No responses yet