android中的bitmap的加載和cache

Android中目前比較常用的緩存策略是LruCache和DiskLruCache,其中LruCache常被用來做內存緩存,而DiskLruCache常被用作存儲緩存。LruCache是Least Recently Used,即最近最少使用算法,這種算法的核心思想是:當緩存快滿時,會淘汰近期最少使用的緩存目標。

高效加載Bitmap的核心思想是採用BitmapFactory.Options來加載圖片所需要的尺寸。通過BitmapFactory.Options來縮放圖片,主要是用到了它的inSampleSize,即採樣率。當inSampleSize爲1時,採樣後的圖片大小爲圖片的原始大小;當insmapleSize大於1時,比如爲2,那麼採樣後的圖片(寬高)就是原始圖片大小(寬高)的1/2,而像素數爲原圖的1/4,其內存佔有率也爲原圖的1/4.即採樣率必須大於1,圖片纔會有縮小的效果,即縮放比例爲1/(inSampleSize的2次方),有一種特殊情況,當inSampleSize小於1時,其作用相當於1,無縮放效果。

獲取採樣率的步驟:

1.將BitmapFactory.Options的inJustDecodeBounds參數設置爲true並加載圖片

2.從BitmapFaction.Options中取出圖片的原始寬高信息,他們對應於outWidth和outHeight參數。

3.根據採樣率的規則並結合目標View所需要的大小計算出採樣率inSmapleSize.

4.將BitmapFactory.Options的inJustDecodeBounds參數設置爲false,然後重新加載圖片。

注:當將從BitmapFactory.Options讀出的參數inJustDecodeBounds設置爲true時,BitmapFactory只負責解析圖片的原始寬高信息,並不會真正的去加載圖片。另外需要注意的是:BitmapFactory獲取的圖片寬高信息和圖片的位置以及程序運行的設備有關。比如一張圖片放在不同的drawable目錄下或者運行在不同屏幕密度的設備之上,可能會導致BitmapFactory獲取到不同的結果。

通常情況下圖片緩存時除了在存儲設備上存儲一份外,還會在內存中存儲一份,這是因爲從內存中加載圖片要比從存儲設備上加載圖片快,可以提高程序的效率,也提高了用戶體驗。

緩存策略主要包含緩存的添加、獲取和刪除三類操作。之所以要進行刪除操作是因爲不管內存換從還是存儲設備緩存,可使用的緩存大小都是有限制的,當緩存容量滿了的時候,但是程序還是要繼續添加緩存,這時候就需要根據某種策略來刪除一些舊的緩存並添加新的緩存。

LruCache是一個泛型類,內部採用一個LinkedHashMap以強引用的方式存儲外界的緩存對象,其提供了get和put方法來完成緩存的獲取和添加操作,當緩存滿是,LruCache會移除較早使用的緩存對象,然後再添加新的緩存對象。

強引用:直接的對象引用

軟引用:當一個對象只有軟引用存在是,系統內存不足時此對象會被GC回收。

弱引用:當一個對象只有弱引用存在時,此對象隨時有可能被GC回收。

DiskLruCache:用於實現存儲設備緩存即磁盤緩存。通過將緩存對象寫入文件系統從而實現緩存效果。

DiskLruCache通過Open方法打開時,會傳入一個版本號的東西,如果傳入的版本不一致,會情況之前所有的緩存文件,所以需傳入固定標識。

DiskLruCache的緩存添加操作是通過Editor完成的,Editor表示一個緩存對象的編輯對象。注意:DiskLruCache不允許同時編輯一個緩存對象。

注意:使用DiskLruCache時,需要做安全校驗,即磁盤緩存所需要的大小是否小於磁盤所剩餘空間的大小。

在快速滑動列表中使用緩存時需要注意View複用和圖片異步加載導致的錯位問題,這時候可以通過url去校驗是否相等。

列表卡頓原因:有圖片時加載網絡圖片屬於耗時操作,用戶頻繁滑動時會產生較多的異步任務,併發量比較高,造成線程池堵塞,或者瞬間更新UI時併發量也比較高。也會造成卡頓,解決方法是在滑動時不進行圖片加載,通過監聽onScrollListener的onScrollChanged方法獲得滑動狀態。也可以通過android:hardwareAccelerated=true爲Activity開啓硬件加速。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章