由于Bitmap的特殊性以及Android對(duì)單個(gè)應(yīng)用所施加的內(nèi)存限制,比如16M,這導(dǎo)致加載Bitmap的時(shí)候很容易出現(xiàn)內(nèi)存溢出。比如以下場(chǎng)景:
java.lang.OutofMemoryError:bitmap size exceeds VM budget
Android中常用的緩存策略也是很有意思,緩存策略一個(gè)通用的思想,可以用到很多場(chǎng)景中,比如在實(shí)際開發(fā)中經(jīng)常需要用到Bitmap做緩存。通過(guò)緩存策略,我們不需要每次都從網(wǎng)絡(luò)上請(qǐng)求圖片或者從存儲(chǔ)設(shè)備中加載圖片,這樣就極大地提高了圖片的加載效率以及產(chǎn)品的用戶體驗(yàn)。目前比較常用的緩存策略是LruCache和DiskLruCache,其中LruCache常被用做內(nèi)存緩存,而DiskLruCache用做存儲(chǔ)緩存。Lru是Least Recently Used的縮寫,即最近最少使用算法,這種算法的核心思想:當(dāng)緩存快滿時(shí),會(huì)淘汰近期最少使用的緩存目標(biāo),很顯然Lru算法的思想是很容易被接受的。
Bitmap的高效加載
Bitmap在Android中指的是一張圖片,可以是png格式也可以是jpg等其他常見的圖片格式。BitmapFactory類提供了四類方法:decodeFile、decodeResource、decodeStream和decodeByteArray,分別用于支持從文件系統(tǒng)、資源、輸入流以及字節(jié)數(shù)組中加載出一個(gè)Bitmap對(duì)象,其中decodeFile和decodeResource又間接調(diào)用了decodeStream方法,這四類方法最終是在Android的底層實(shí)現(xiàn)的,對(duì)應(yīng)著BitmapFactory類的幾個(gè)native方法。
如何高效地加載Bitmap呢,其實(shí)核心思想也簡(jiǎn)單,那就是采用BitmapFactory.Options來(lái)加載所需尺寸的圖片。主要是用到它的inSampleSize參數(shù),即采樣率。當(dāng)inSampleSize為1時(shí),采樣后的圖片大小為圖片的原始大小,當(dāng)inSampleSize大于1時(shí),比如為2,那么采樣后的圖片其寬/寬均為原圖大小的1/2,而像素?cái)?shù)為原圖的1/4,其占有的內(nèi)存大小也為原圖的1/4。從最新官方文檔中指出,inSampleSize的取值應(yīng)該是2的指數(shù),比如1、2、4、8、16等等。
通過(guò)采樣率即可有效地加載圖片,那么到底如何獲取采樣率呢,獲取采樣率也很簡(jiǎn)單,循序如下流程: