Android 兩種緩存方式介紹

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 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ù)的目錄
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仁期,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌跛蛋,老刑警劉巖熬的,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赊级,居然都是意外死亡押框,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門此衅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來强戴,“玉大人,你說我怎么就攤上這事挡鞍∑锎酰” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵墨微,是天一觀的道長道媚。 經(jīng)常有香客問我,道長翘县,這世上最難降的妖魔是什么最域? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮锈麸,結(jié)果婚禮上镀脂,老公的妹妹穿的比我還像新娘。我一直安慰自己忘伞,他們只是感情好薄翅,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著氓奈,像睡著了一般翘魄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舀奶,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天暑竟,我揣著相機與錄音,去河邊找鬼育勺。 笑死但荤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的涧至。 我是一名探鬼主播纱兑,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼化借!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捡多,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蓖康,失蹤者是張志新(化名)和其女友劉穎铐炫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蒜焊,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡倒信,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了泳梆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鳖悠。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖优妙,靈堂內(nèi)的尸體忽然破棺而出乘综,到底是詐尸還是另有隱情,我是刑警寧澤套硼,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布卡辰,位于F島的核電站,受9級特大地震影響邪意,放射性物質(zhì)發(fā)生泄漏九妈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一雾鬼、第九天 我趴在偏房一處隱蔽的房頂上張望萌朱。 院中可真熱鬧,春花似錦策菜、人聲如沸晶疼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冒晰。三九已至,卻和暖如春竟块,著一層夾襖步出監(jiān)牢的瞬間壶运,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工浪秘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蒋情,地道東北人。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓耸携,卻偏偏與公主長得像棵癣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子夺衍,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容