什麼是緩存?算法
緩存技術原理就是把用戶訪問的全部對象看做一個全集,通過算法標記哪些是用戶常常訪問的對象,把這些對象放到一個集合裏,這個集合是全集一個子集,下一次用戶再訪問的時候會先從這個子集集合中查找用戶要訪問的對象若是找到就直接返回這個對象,若是沒有找到則再去全集中查找。固然了我這裏說的只是原理性的東西,緩存是有不少算法的,而且有的不止一級緩存,這裏就不過多講了。緩存
爲何要用到緩存?安全
有緩存的話能夠沒必要每次從源地址讀取文件,既節省了時間也節省了流量。尤爲是手機設備,頻繁的訪問網絡資源會消耗不少用戶的流量和電量,這是用戶不能忍受的,因此不管從哪一個方面考慮應用程序都必須加上緩存。網絡
Android中的圖片緩存有哪些?各有什麼特色?ide
Android設備的圖片緩存分兩種,一種是內存緩存,圖片緩存在設備的內存中,一種是外部緩存,圖片緩存在磁盤上,磁盤能夠是內部的存儲空間也能夠是外部的sd卡。這兩種緩存各有各的優勢,內存緩存優勢是快,缺點是由於也是讀取到內存中因此也會消耗內存,因此不能太大,用的時候要考慮分配的空間,還有一個缺點是應用重啓後就會消失。外部緩存的優勢是能夠長久保存大量的數據(相比較內存緩存而言),缺點就是慢。工具
內存緩存:google
在Android中官網推薦使用LruCache做爲內存緩存,LruCache實際上就是一個LinkedHashMap( 補充知識:LinkedHashMap是一個雙向循環列表,不支持線程安全,LruCache對它進行了封裝添加了線程安全操做),裏面保存了必定數量的對象強引用,每次添加的新對象都是在鏈表的頭,當分配的空間用完的時候會把末尾的對象移除,移除的對象就能夠被gc回收了。這裏須要注意一下LruCache的容量,這個容量既不能太大,會形成OOM,又不能過小,起不到緩存的做用。google官網給出一下意見做爲參考:spa
·分配LruCache大小的時候考慮你的應用剩餘內存有多大;線程
·一次屏幕顯示多少張圖片,有多少張圖片是緩存起來準備顯示的;對象
·考慮你的手機分辨率和尺寸, 緩存相同的圖片個數,dpi越大的手機須要的內存就會越大;
·圖片分辨率和像素質量也決定了佔用內存的大小;
·圖片訪問的頻繁程度是多少,是否是有一些圖片是常常訪問的?若是存在你能夠考慮用多個·LruCache來作緩存,按照訪問的頻率度分配到不一樣的LruCache中;
·如何平衡一下圖片質量和數量,有些時候能夠考慮緩存低分辨率的圖片,用到的時候再在後臺請求更高質量的圖片;
·總之你分配的LruCache大小既不能太大,又不能過小,具體到應用中還要你綜合考慮。
下面的代碼是使用LruCache的例子:
1 private LruCache<String, Bitmap> mMemoryCache;//聲明緩存空間
2 final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);//獲取應用在系統中的最大內存分配
3 //分配1/8的應用內存做爲緩存空間
4 final int cacheSize = maxMemory / 8;
5 mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
6 @Override
7 protected int sizeOf(String key, Bitmap bitmap) {
8 //重寫sizeOf方法,返回圖片的佔用字節數而不是圖片的個數,每次添加圖片是會被調用
9 return bitmap.getByteCount() / 1024;
10 }
11 };
注意:有同窗可能會問下面的代碼:
1 intcacheSize=4*1024*1024;// 4MiB
2 LruCachebitmapCache=newLruCache(cacheSize){
3 protectedintsizeOf(Stringkey,Bitmapvalue){
4 returnvalue.getByteCount();
5 }
6 }
這兩個sizeOf的計算是不同的,這裏說明一下,這個方法重寫的目的是返回圖片佔用的緩存空間而不是圖片的數目,而且這個數值的單位要和cacheSize同樣。
總結:
綜合上面的講解,在使用內存緩存LruCache時你須要知道以下知識:
LruCache封裝了LinkedHashMap,提供了LRU(Least Recently Used 最近最少使用算法)緩存的功能;
LruCache經過trimToSize方法自動刪除最近最少訪問的鍵值對;
LruCache不容許空鍵值, LinkedHashMap容許;
LruCache線程安全, LinkedHashMap線程不安全;
繼承LruCache時,必需要複寫sizeOf方法,用於計算每一個條目的大小。在put和get的時候會調用safeSizeOf(K key, V value),safeSizeOf(K key, V value)會調用 sizeOf (K key, V value),這個方法默認返回1。
另外推薦一款第三方的內測工具對APP進行全方面的檢測:http://www.ineice.com/