本章主要學習bitmap的載入和cache,由於bitmap的特殊性以及android對單個應用所施加的記憶體限制,導致載入bitmap很容易出現記憶體溢位,因此這裡主要**下如何高效地載入bitmap以及其中所使用的的快取策略.
一.bitmap的高效載入
1.核心思想
按一定的取樣率把縮小後再載入.
2.核心類和核心引數
(1)bitmapfactor提供了四類方法載入:
//從檔案系統載入乙個bitmap物件(2)bitmapfactory.options縮放decodefile
//從資源載入乙個bitmap物件
decoderesource
//從輸入流載入乙個bitmap物件
decodestream
//從位元組陣列載入乙個bitmap物件
decodebytearray
注意:decodefile和decoderesource又間接呼叫了decodestream方法
通過bitmapfactory.options來縮放,主要用到了insamplesize引數,即取樣率.
a.insamplesize的取值
應總是為2的指數b.insamplesize的變化如不為2的指數,那麼系統會向下取整並選擇乙個最接近的2的指數來代替,比如3,系統會選擇2來代替
值k為1時,取樣後的大小為的原始大小(3)injustdecodebounds引數值k小於1時,其作用相當於1,無縮放效果
值k大於1時,取樣後的寬高為原圖的1/k,畫素為原圖的1/k^2,
占用記憶體為原圖的1/k^2
值為true時,bitmapfactory只會解析的原始寬高資訊,並不會真正地載入3.獲取取樣率的流程值為false時,真正的載入到記憶體
(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...