Android用LruCache(Least recently use Cache 意思就是最近使用次數(shù)最少的那個(gè)對(duì)象)來(lái)取代原來(lái)強(qiáng)引用和軟引用實(shí)現(xiàn)內(nèi)存緩存扔役,因?yàn)閾?jù)說(shuō)自2.3以后Android將更頻繁的調(diào)用GC朝捆,導(dǎo)致軟引用緩存的數(shù)據(jù)極易被釋放。
LruCache使用一個(gè)LinkedHashMap簡(jiǎn)單的實(shí)現(xiàn)內(nèi)存的緩存殿较,沒(méi)有軟引用,都是強(qiáng)引用。如果添加的數(shù)據(jù)大于設(shè)置的最大值凑术,就刪除最先緩存的數(shù)據(jù)來(lái)調(diào)整內(nèi)存挽霉。
他的主要原理在trimToSize方法中防嗡。
首先是LruCache聲明的變量
然后直接看關(guān)鍵方法trimToSize
這個(gè)方法是一個(gè)無(wú)限循環(huán),跳出循環(huán)的條件是侠坎,size < maxSize或者 map 為空蚁趁。主要的功能是判斷當(dāng)前容量時(shí)候已經(jīng)超出最大的容量,如果超出了maxSize的話实胸,就會(huì)循環(huán)移除map中的第一個(gè)元素他嫡,直到達(dá)到跳出循環(huán)的條件。
而雙向鏈表LinkedHashMap(3個(gè)參數(shù)構(gòu)造方法中accessOrder排序模式設(shè)置為訪問(wèn)模式時(shí))中庐完,每次get和put數(shù)據(jù)钢属,則會(huì)將改對(duì)象移到鏈表的尾部,這樣子內(nèi)存緩存達(dá)到最大值時(shí)假褪,map中的第一個(gè)元素就是最近最少使用的那個(gè)元素署咽。此時(shí)近顷,把它刪除生音,從而達(dá)到避免OOM的出現(xiàn)。
注釋1處safeSizeOf中封裝了sizeOf方法窒升,它是用來(lái)計(jì)算單個(gè)對(duì)象的大小缀遍,這里默認(rèn)返回1,一般需要重寫(xiě)該方法來(lái)計(jì)算對(duì)象的大小饱须,如果是計(jì)算bitmap的大小域醇,這里會(huì)重寫(xiě)不返回1,而是返回bitmap的大小bitmap.getRowBytes() * bitmap.getHeight()
這里設(shè)置了maxSize,以及實(shí)例化了一個(gè)LinkedHashMap對(duì)象蓉媳,這個(gè)LinkedHashMap對(duì)象是實(shí)現(xiàn)Lru算法的關(guān)鍵譬挚,注釋1處表示創(chuàng)建一個(gè)初始容量為0,加載因子是0.75(容量達(dá)到75%的時(shí)候把空間增大1半)酪呻,最后這個(gè)參數(shù)上面也說(shuō)了减宣,是accessOrder,意思是排序模式玩荠,這里是true表示排序模式為訪問(wèn)模式(當(dāng)map中數(shù)據(jù)有put和get時(shí)漆腌,當(dāng)前操作的數(shù)據(jù)會(huì)移動(dòng)到鏈表尾部)
看注釋?xiě)?yīng)該明白了,先是增加size阶冈,然后判斷以前有沒(méi)有值闷尿,如果有就更新當(dāng)前的額值,并且size要減去以前的值的大小
entryRemoved是一個(gè)空實(shí)現(xiàn)女坑,如果我們使用LruCache的時(shí)候需要掌握元素移除的信息填具,可以重寫(xiě)這個(gè)方法來(lái)獲取元素移除的信息。
轉(zhuǎn)自:http://www.reibang.com/p/e07fca15271a