什么是緩存羞秤?
緩存技術(shù)原理就是把用戶訪問的所有對象看作一個全集来候,經(jīng)過算法標(biāo)記哪些是用戶經(jīng)常訪問的對象跷叉,把這些對象放到一個集合里,這個集合是全集一個子集营搅,下一次用戶再訪問的時候會先從這個子集集合中查找用戶要訪問的對象如果找到就直接返回這個對象云挟,如果沒有找到則再去全集中查找。當(dāng)然了我這里說的只是原理性的東西转质,緩存是有很多算法的园欣,并且有的不止一級緩存,這里就不過多講了休蟹。
為什么要用到緩存沸枯?
有緩存的話可以不必每次從源地址讀取文件,既節(jié)省了時間也節(jié)省了流量赂弓。尤其是手機(jī)設(shè)備绑榴,頻繁的訪問網(wǎng)絡(luò)資源會消耗很多用戶的流量和電量,這是用戶不能忍受的拣展,所以無論從哪個方面考慮應(yīng)用程序都必須加上緩存彭沼。
Android中的圖片緩存有哪些?各有什么特點备埃?
Android設(shè)備的圖片緩存分兩種姓惑,一種是內(nèi)存緩存,圖片緩存在設(shè)備的內(nèi)存中按脚,一種是外部緩存于毙,圖片緩存在磁盤上,磁盤可以是內(nèi)部的存儲空間也可以是外部的sd卡辅搬。這兩種緩存各有各的優(yōu)點唯沮,內(nèi)存緩存優(yōu)點是快,缺點是因為也是讀取到內(nèi)存中所以也會消耗內(nèi)存堪遂,所以不能太大介蛉,用的時候要考慮分配的空間,還有一個缺點是應(yīng)用重啟后就會消失溶褪。外部緩存的優(yōu)點是可以長久保存大量的數(shù)據(jù)(相比較內(nèi)存緩存而言)币旧,缺點就是慢。
內(nèi)存緩存:
在Android中官網(wǎng)推薦使用LruCache作為內(nèi)存緩存猿妈,LruCache實際上就是一個LinkedHashMap(補(bǔ)充知識:LinkedHashMap是一個雙向循環(huán)列表吹菱,不支持線程安全巍虫,LruCache對它進(jìn)行了封裝添加了線程安全操作),里面保存了一定數(shù)量的對象強(qiáng)引用鳍刷,每次添加的新對象都是在鏈表的頭占遥,當(dāng)分配的空間用完的時候會把末尾的對象移除,移除的對象就可以被gc回收了输瓜。這里需要注意一下LruCache的容量瓦胎,這個容量既不能太大,會造成OOM前痘,又不能太小凛捏,起不到緩存的作用。google官網(wǎng)給出一下意見作為參考:
·分配LruCache大小的時候考慮你的應(yīng)用剩余內(nèi)存有多大芹缔;
·一次屏幕顯示多少張圖片坯癣,有多少張圖片是緩存起來準(zhǔn)備顯示的;
·考慮你的手機(jī)分辨率和尺寸最欠,緩存相同的圖片個數(shù)示罗,dpi越大的手機(jī)需要的內(nèi)存就會越大;
·圖片分辨率和像素質(zhì)量也決定了占用內(nèi)存的大兄ビ病蚜点;
·圖片訪問的頻繁程度是多少,是不是有一些圖片是經(jīng)常訪問的拌阴?如果存在你可以考慮用多個·LruCache來做緩存绍绘,按照訪問的頻率度分配到不同的LruCache中;
·如何平衡一下圖片質(zhì)量和數(shù)量迟赃,有些時候可以考慮緩存低分辨率的圖片陪拘,用到的時候再在后臺請求更高質(zhì)量的圖片;
·總之你分配的LruCache大小既不能太大纤壁,又不能太小左刽,具體到應(yīng)用中還要你綜合考慮。
下面的代碼是使用LruCache的例子:
1private LruCache mMemoryCache;//聲明緩存空間
2final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);//獲取應(yīng)用在系統(tǒng)中的最大內(nèi)存分配
3//分配1/8的應(yīng)用內(nèi)存作為緩存空間
4finalint cacheSize = maxMemory / 8;
5mMemoryCache= new LruCache(cacheSize) {
6@Override
7protectedint sizeOf(String key, Bitmap bitmap) {
8//重寫sizeOf方法酌媒,返回圖片的占用字節(jié)數(shù)而不是圖片的個數(shù)欠痴,每次添加圖片是會被調(diào)用
9returnbitmap.getByteCount() / 1024;
10}
11};
注意:有同學(xué)可能會問下面的代碼:
1intcacheSize=4*1024*1024;//4MiB
2LruCachebitmapCache=newLruCache(cacheSize){
3protectedintsizeOf(Stringkey,Bitmapvalue){
4returnvalue.getByteCount();
5}
6}
這兩個sizeOf的計算是不一樣的,這里說明一下秒咨,這個方法重寫的目的是返回圖片占用的緩存空間而不是圖片的數(shù)目喇辽,并且這個數(shù)值的單位要和cacheSize一樣。
總結(jié):
綜合上面的講解雨席,在使用內(nèi)存緩存LruCache時你需要知道如下知識:
LruCache封裝了LinkedHashMap茵臭,提供了LRU(Least
Recently Used最近最少使用算法)緩存的功能;
LruCache通過trimToSize方法自動刪除最近最少訪問的鍵值對;
LruCache不允許空鍵值旦委,LinkedHashMap允許;
LruCache線程安全雏亚,LinkedHashMap線程不安全缨硝;
繼承LruCache時,必須要復(fù)寫sizeOf方法罢低,用于計算每個條目的大小查辩。在put和get的時候會調(diào)用safeSizeOf(K key,
V value),safeSizeOf(K key, V
value)會調(diào)用sizeOf (K key, V
value)网持,這個方法默認(rèn)返回1宜岛。
另外推薦一款第三方的在線內(nèi)測工具對APP進(jìn)行全方面的檢測:http://www.ineice.com/