Android緩存分為內(nèi)存緩存和磁盤緩存。
內(nèi)存緩存(LruCache)
在早期的 Android 2.x 時代约巷,常用的緩存方式是軟引用(SoftReference)和弱引用(WeakReference)谣膳,如大部分的使用方式:HashMap<String url, SoftReference<Drawable>> imageCache;這種形式颁糟。從Android 2.3(Level 9)開始光涂,垃圾回收器更傾向于回收 SoftReference 或 WeakReference 對象齐唆,這使得 SoftReference和 WeakReference 變得不是那么實用有效律秃。
同時爬橡,到了Android 3.0(Level 11)之后,圖片數(shù)據(jù)Bitmap被放置到了內(nèi)存的堆區(qū)域棒动,而堆區(qū)域的內(nèi)存是由GC管理的糙申,開發(fā)者也就不需要進行圖片資源的釋放工作,但這也使得圖片數(shù)據(jù)的釋放無法預(yù)知迁客,增加了造成OOM的可能郭宝。
因此辞槐,在Android3.1以后,Android推出了LruCache這個內(nèi)存緩存類粘室,LruCache中的對象是強引用的榄檬。
LruCache 是 Android 3.1 開始提供的一種基于內(nèi)存的緩存框架,LRU 是 Least Recently Used 的縮寫衔统,即最近最少使用鹿榜。當一塊內(nèi)存最近很少使用的時候就會被從緩存中移除。它內(nèi)部采用一個 LinkedHashMap 以強引用的方式存儲外界的緩存對象锦爵,其提供了get和put方法來完成緩存的獲取和添加操作舱殿,當緩存滿時,LruCache 會移除較早的緩存對象险掀,然后再添加新的緩存對象沪袭。
LruCache 是線程安全的。
-
使用 LruCache
SDK 自帶樟氢,可直接使用冈绊。
注意:LruCache 從 Android 3.1 開始已經(jīng)作為 android 源碼的一部分維護在 android 系統(tǒng)中,為了兼容以前的版本埠啃, android 的 support-v4 包也提供了 LruCache 的維護死宣。如果 App 需要兼容到 android 3.1 之前的版本就需要使用 support-v4 包中的 LruCache,如果不需要兼容到 android 3.1 則直接使用android 源碼中的 LruCache 即可碴开。
-
LruCache 常用 API
方法名 釋義 LruCache(int maxSize) 實例化 Lru毅该,需要傳入緩存的最大值,這個最大值可以是個數(shù),比如對象的個數(shù)潦牛,也可以是內(nèi)存的大小 resize(int maxSize) 重置最大存儲空間 get(K key) 通過 key 返回相應(yīng)的 item眶掌,或者創(chuàng)建返回相應(yīng)的 item。相應(yīng)的item會移動到隊列的頭部巴碗,如果 item 的value沒有被 cache 或者不能被創(chuàng)建畏线,則返回 null。 put(K key, V value) 創(chuàng)建 cache 項良价,并將創(chuàng)建的項放到隊列的頭部 trimToSize(int maxSize) 清空 cache 空間 remove(K key) 刪除 key 相應(yīng)的 cache 項,返回相應(yīng)的 value create(K key 當某 Item 丟失時會調(diào)用到蒿叠,返回計算的相應(yīng)的 value 或者 null sizeOf(K key, V value) 這個方法要特別注意明垢,跟我們實例化 LruCache 的 maxSize 要呼應(yīng),怎么做到呼應(yīng)呢市咽,比如 maxSize 的大小為緩存的個數(shù)痊银,這里就是 return 1就 ok,如果是內(nèi)存的大小施绎,如果5 M溯革,這個就不能是個數(shù)了贞绳,就需要覆蓋這個方法,返回每個緩存 value 的size大小致稀,如果是 Bitmap冈闭,這應(yīng)該是 bitmap.getByteCount(); evictAll() 清空 cache evictionCount() 返回被回收的數(shù)量 snapshot() 返回當前cache的副本,從最近最少訪問到最多訪問
磁盤緩存(DiskLruCache)
DiskLruCache 不同于 LruCache抖单,LruCache 是將數(shù)據(jù)緩存到內(nèi)存中去萎攒,而 DiskLruCache 是外部緩存,例如可以將網(wǎng)絡(luò)下載的圖片永久的緩存到手機外部存儲中去矛绘,并可以將緩存數(shù)據(jù)取出來使用耍休。
DiskLruCache 不是 Android 自帶類,是大神 JakeWharton 開源的货矮,但是得到了官方推薦羊精。DiskLruCache 沒有編寫到 SDK 中,如需使用可直接 copy 這個類到項目中去囚玫。
-
使用 DiskLruCache
-
直接代碼中引用
compile 'com.jakewharton:disklrucache:2.0.2'
DiskLruCache 常用 API
方法名 | 釋義 |
---|---|
DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize) | DiskLruCache 實例化方法喧锦。作用是打開一個緩存目錄,如果沒有則首先創(chuàng)建它劫灶。directory:指定數(shù)據(jù)緩存地址裸违;appVersion:APP版本號,當版本號改變時本昏,緩存數(shù)據(jù)會被清除 供汛;valueCount:同一個key可以對應(yīng)多少文件 ;maxSize:最大可以緩存的數(shù)據(jù)量涌穆。 |
Editor edit(String key) | 通過key可以獲得一個DiskLruCache.Editor怔昨,通過Editor可以得到一個輸出流,進而緩存到本地存儲上宿稀。 |
void flush() | 強制緩沖文件保存到文件系統(tǒng) |
Snapshot get(String key) | 通過key值來獲得一個Snapshot趁舀,如果Snapshot存在,則移動到LRU隊列的頭部來祝沸,通過Snapshot可以得到一個輸入流InputStream |
long size() | 緩存數(shù)據(jù)的大小矮烹,單位是byte |
boolean remove(String key) | 根據(jù)key值來刪除對應(yīng)的數(shù)據(jù),如果該數(shù)據(jù)正在被編輯罩锐,則不能刪除 |
void delete() | 關(guān)閉緩存并且刪除目錄下所有的緩存數(shù)據(jù)奉狈,即使有的數(shù)據(jù)不是由DiskLruCache 緩存到本目錄的 |
void close() | 關(guān)閉DiskLruCache,緩存數(shù)據(jù)會保留在外存中 |
boolean isClosed() | 判斷DiskLruCache是否關(guān)閉涩惑,返回true表示已關(guān)閉 |
File getDirectory() | 緩存數(shù)據(jù)的目錄 |