Bitmap的載入和快取策略

2021-10-05 10:33:10 字數 4685 閱讀 7900

本章主要學習bitmap的載入和cache,由於bitmap的特殊性以及android對單個應用所施加的記憶體限制,導致載入bitmap很容易出現記憶體溢位,因此這裡主要**下如何高效地載入bitmap以及其中所使用的的快取策略.

一.bitmap的高效載入

1.核心思想

按一定的取樣率把縮小後再載入.

2.核心類和核心引數

(1)bitmapfactor提供了四類方法載入:

//從檔案系統載入乙個bitmap物件

decodefile

//從資源載入乙個bitmap物件

decoderesource

//從輸入流載入乙個bitmap物件

decodestream

//從位元組陣列載入乙個bitmap物件

decodebytearray

注意:decodefile和decoderesource又間接呼叫了decodestream方法

(2)bitmapfactory.options縮放

通過bitmapfactory.options來縮放,主要用到了insamplesize引數,即取樣率.

a.insamplesize的取值

應總是為2的指數

如不為2的指數,那麼系統會向下取整並選擇乙個最接近的2的指數來代替,比如3,系統會選擇2來代替

b.insamplesize的變化

值k為1時,取樣後的大小為的原始大小

值k小於1時,其作用相當於1,無縮放效果

值k大於1時,取樣後的寬高為原圖的1/k,畫素為原圖的1/k^2,占用記憶體為原圖的1/k^2

(3)injustdecodebounds引數

值為true時,bitmapfactory只會解析的原始寬高資訊,並不會真正地載入

值為false時,真正的載入到記憶體

3.獲取取樣率的流程

(1)將bitmapfactory.options的injustdecodebounds引數設為true,並載入.

(2)從bitmapfactory.options取出原始的寬高資訊,他們對應於outwidth和outheight引數.

(3)根據取樣率的規則並結合目標view所需的大小計算出取樣率.

4.**實現

/**

* 對乙個resources的資源檔案進行指定長寬來載入進記憶體, 並把這個bitmap物件返回

** @param res 資源檔案物件

* @param resid 要操作的id

* @param reqwidth 最終想要得到bitmap的寬度

* @param reqheight 最終想要得到bitmap的高度

* @return 返回取樣之後的bitmap物件

*/public static bitmap decodesampledbitmapfromresource(resources res, int resid, int reqwidth, int reqheight)

/*** 乙個計算工具類的方法, 傳入的屬性物件和想要實現的目標寬高. 通過計算得到取樣值

* @param options 要操作的原始屬性

* @param reqwidth 最終想要得到bitmap的寬度

* @param reqheight 最終想要得到bitmap的高度

* @return 返回取樣率

*/private static int calculateinsamplesize(bitmapfactory.options options, int reqheight, int reqwidth)

}

return insamplesize;

}//載入乙個畫素為100*100的imageview

mimageview.setimagebitmap(decodesampledbitmapfromresource(getresources(),r.mipmap.ic_launcher,100,100);

二.快取策略

1.概述

使用快取的目的是為了避免過多的流量消耗,快取策略主要包含快取的新增,獲取和刪除這三類操作,如何對這些快取進行操作就是一種策略,不同的策略對應著不同的快取演算法,目前常用的一種快取演算法是lru(least recently used),lru是近期最少使用演算法,他的核心思想是當快取滿時,會優先淘汰那些近期最少使用的快取物件.採用lru演算法的快取有兩種:lrucache和disklrucache.

(1)lrucache

lrucache用於實現記憶體快取.它是乙個泛型類.內部採用乙個linkedhashmap以強引用的方式儲存外界的快取物件,其提供了get和put方法來完成快取的獲取和新增操作,當快取滿時,lrucacche會移除較早使用的快取物件,然後再新增新的快取物件.這裡使用了強引用,因此這裡要明白一下強引用,軟應用和若引用的區別:

強引用:直接的物件引用

軟引用:當乙個物件只有軟引用存在時,系統記憶體不足時此物件會被gc**

弱應用,當乙個物件只有弱引用存在時,此物件會隨時被gc**.

具體的實現:

a.計算當前可用記憶體的大小

b.分配lrucache快取容量

c.建立lrucache物件並傳入lrucache的快取容量,複寫sizeof方法,計算快取物件的大小.

d.通過put,get和remove方法.實現快取的新增,獲取和刪除.

//獲取當前程序可用記憶體大小

int maxmemory = (int)(runtime.getruntime().maxmemory())/1024;

//獲取快取的總容量

int cachesize = maxmemory/8;

//建立lrucache物件

mlrucache = new lrucache(cachesize)

};//新增快取物件

mlrucache.put("test1",bitmap1);

mlrucache.put("test2",bitmap2);

//獲取快取物件

mlrucache.get("test1");

//刪除快取物件

mlrucache.remove("test2");

(2)dislrucache

dislrucache用於實現儲存裝置快取,即磁碟快取.,它通過將快取物件寫入檔案系統從而實現快取的效果.

使用步驟:

a.設定dislrucache的容量.

b.設定快取目錄.

c.通過open的方法,建立dislrucache物件.

d.利用editor,snapshop和remove實現資料的新增,獲取和刪除.

e.呼叫flush將資料寫入磁碟.

//使用disklrucach需要新增新增依賴

//implementation 'com.jakewharton:disklrucache:2.0.2'

public class disklrucacheutil

//引數1傳入儲存路徑

//引數2傳入應用的版本號,一般設定為1,當版本號改變會清空之前的所有的快取檔案,在實際開發中,版本號改變,很多情況下快取檔案仍然有效

//引數3傳入單個節點對應的資料的個數,一般設定為1即可

//引數4傳入快取的總大小

mdislrucache = disklrucache.open(diskcachedir, 1, 1, disk_cache_size);

} catch (ioexception e)

}private file getdiscachedir(context context, string filename) else

return new file(cachepath+file.separator+filename);

}//dislrucache新增資料

public void adddislrucachedata(string url,string data) catch (ioexception e)

}//dislrucache查詢資料

public string getdislrucachedata(string url)

} catch (ioexception e)

return sb.tostring();

}//dislrucache刪除資料

public void deletedislrucachedata(string url) catch (ioexception e)

}private string hashkeyfromurl(string url) catch (nosuchalgorithmexception e)

return cachekey;

}private string bytestohexstring(byte bytes)

}return sb.tostring();

}}

Bitmap的載入與快取

android系統中一般用bitmap物件表示,它支援png,jpg等常見格式。通常情況下的體積都比較大,單個應用允許使用的記憶體又是有限的,所以我們需要採取一些手段減少記憶體占用並提高載入速度。假設我們用imageview顯示,通常它的尺寸要比的尺寸小很多,那麼把整個載入進記憶體顯然是沒有必要的。...

常見快取演算法和快取策略

快取演算法 快取法通過設計良好的資料分塊 預取 順序預取 快取替換等演算法來提高對快取內容的命中率。快取演算法可以分為基於訪問時間的策略 基於訪問頻率的策略 訪問時間與頻率兼顧策略 時間距離分布策略等型別。快取策略 快取策略主要三方面 對於第二方面,大部分快取演算法使用預取策略來提前將部分磁碟資料放...

Mybatis的延遲載入和快取

1.mybatis中的延遲載入,也稱為懶載入,是指在進行關聯查詢時,按照設定延遲載入規則推遲對關聯物件的select查詢。延遲載入可以有效的減少資料庫壓力。注意 mybatis的延遲載入只是對關聯物件的查詢有延遲設定,對於主載入物件都是直接執行查詢語句的。2.mybatis根據對關聯物件查詢的sel...