摘自:http://blog.csdn.net/linghu_java/article/details/8574102
- packageandroid.util;
-
- importjava.util.LinkedHashMap;
- importjava.util.Map;
-
- /**
- *Acachethatholdsstrongreferencestoalimitednumberofvalues.Eachtime
- *avalueisaccessed,itismovedtotheheadofaqueue.Whenavalueis
- *addedtoafullcache,thevalueattheendofthatqueueisevictedandmay
- *becomeeligibleforgarbagecollection.
- *Cache保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部。
- * 当cache已满的时候加入新的item时,在队列尾部的item会被回收。
- *<p>Ifyourcachedvaluesholdresourcesthatneedtobeexplicitlyreleased,
- *override{@link#entryRemoved}.
- *如果你cache的某个值需要明确释放,重写entryRemoved()
- *<p>Ifacachemissshouldbecomputedondemandforthecorrespondingkeys,
- *override{@link#create}.Thissimplifiesthecallingcode,allowingitto
- *assumeavaluewillalwaysbereturned,evenwhenthere'sacachemiss.
- *如果key相对应的item丢掉啦,重写create().这简化了调用代码,即使丢失了也总会返回。
- *<p>Bydefault,thecachesizeismeasuredinthenumberofentries.Override
- *{@link#sizeOf}tosizethecacheindifferentunits.Forexample,thiscache
- *islimitedto4MiBofbitmaps:默认cache大小是测量的item的数量,重写sizeof计算不同item的
- * 大小。
- *<pre>{@code
- *intcacheSize=4*1024*1024;//4MiB
- *LruCache<String,Bitmap>bitmapCache=newLruCache<String,Bitmap>(cacheSize){
- *protectedintsizeOf(Stringkey,Bitmapvalue){
- *returnvalue.getByteCount();
- *}
- *}}</pre>
- *
- *<p>Thisclassisthread-safe.Performmultiplecacheoperationsatomicallyby
- *synchronizingonthecache:<pre>{@code
- *synchronized(cache){
- *if(cache.get(key)==null){
- *cache.put(key,value);
- *}
- *}}</pre>
- *
- *<p>Thisclassdoesnotallownulltobeusedasakeyorvalue.Areturn
- *valueofnullfrom{@link#get},{@link#put}or{@link#remove}is
- *unambiguous:thekeywasnotinthecache.
- * 不允许key或者value为null
- * 当get(),put(),remove()返回值为null时,key相应的项不在cache中
- */
- publicclassLruCache<K,V>{
- privatefinalLinkedHashMap<K,V>map;
-
- /**Sizeofthiscacheinunits.Notnecessarilythenumberofelements.*/
- privateintsize; //已经存储的大小
- privateintmaxSize; //规定的最大存储空间
-
- privateintputCount; //put的次数
- privateintcreateCount; //create的次数
- privateintevictionCount; //回收的次数
- privateinthitCount; //命中的次数
- privateintmissCount; //丢失的次数
-
- /**
- *@parammaxSizeforcachesthatdonotoverride{@link#sizeOf},thisis
- *themaximumnumberofentriesinthecache.Forallothercaches,
- *thisisthemaximumsumofthesizesoftheentriesinthiscache.
- */
- publicLruCache(intmaxSize){
- if(maxSize<=0){
- thrownewIllegalArgumentException("maxSize<=0");
- }
- this.maxSize=maxSize;
- this.map=newLinkedHashMap<K,V>(0,0.75f,true);
- }
-
- /**
- *Returnsthevaluefor{@codekey}ifitexistsinthecacheorcanbe
- *createdby{@code#create}.Ifavaluewasreturned,itismovedtothe
- *headofthequeue.Thisreturnsnullifavalueisnotcachedandcannot
- *becreated.通过key返回相应的item,或者创建返回相应的item。相应的item会移动到队列的头部,
- * 如果item的value没有被cache或者不能被创建,则返回null。
- */
- publicfinalVget(Kkey){
- if(key==null){
- thrownewNullPointerException("key==null");
- }
-
- VmapValue;
- synchronized(this){
- mapValue=map.get(key);
- if(mapValue!=null){
- hitCount++; //命中
- returnmapValue;
- }
- missCount++; //丢失
- }
-
- /*
- *Attempttocreateavalue.Thismaytakealongtime,andthemap
- *maybedifferentwhencreate()returns.Ifaconflictingvaluewas
- *addedtothemapwhilecreate()wasworking,weleavethatvaluein
- *themapandreleasethecreatedvalue.
- * 如果丢失了就试图创建一个item
- */
-
- VcreatedValue=create(key);
- if(createdValue==null){
- returnnull;
- }
-
- synchronized(this){
- createCount++;//创建++
- mapValue=map.put(key,createdValue);
-
- if(mapValue!=null){
- //Therewasaconflictsoundothatlastput
- //如果前面存在oldValue,那么撤销put()
- map.put(key,mapValue);
- }else{
- size+=safeSizeOf(key,createdValue);
- }
- }
-
- if(mapValue!=null){
- entryRemoved(false,key,createdValue,mapValue);
- returnmapValue;
- }else{
- trimToSize(maxSize);
- returncreatedValue;
- }
- }
-
- /**
- *Caches{@codevalue}for{@codekey}.Thevalueismovedtotheheadof
- *thequeue.
- *
- *@returnthepreviousvaluemappedby{@codekey}.
- */
- publicfinalVput(Kkey,Vvalue){
- if(key==null||value==null){
- thrownewNullPointerException("key==null||value==null");
- }
-
- Vprevious;
- synchronized(this){
- putCount++;
- size+=safeSizeOf(key,value);
- previous=map.put(key,value);
- if(previous!=null){ //返回的先前的value值
- size-=safeSizeOf(key,previous);
- }
- }
-
- if(previous!=null){
- entryRemoved(false,key,previous,value);
- }
-
- trimToSize(maxSize);
- returnprevious;
- }
-
- /**
- *@parammaxSizethemaximumsizeofthecachebeforereturning.Maybe-1
- *toevicteven0-sizedelements.
- * 清空cache空间
- */
- privatevoidtrimToSize(intmaxSize){
- while(true){
- Kkey;
- Vvalue;
- synchronized(this){
- if(size<0||(map.isEmpty()&&size!=0)){
- thrownewIllegalStateException(getClass().getName()
- +".sizeOf()isreportinginconsistentresults!");
- }
-
- if(size<=maxSize){
- break;
- }
-
- Map.Entry<K,V>toEvict=map.eldest();
- if(toEvict==null){
- break;
- }
-
- key=toEvict.getKey();
- value=toEvict.getValue();
- map.remove(key);
- size-=safeSizeOf(key,value);
- evictionCount++;
- }
-
- entryRemoved(true,key,value,null);
- }
- }
-
- /**
- *Removestheentryfor{@codekey}ifitexists.
- *删除key相应的cache项,返回相应的value
- *@returnthepreviousvaluemappedby{@codekey}.
- */
- publicfinalVremove(Kkey){
- if(key==null){
- thrownewNullPointerException("key==null");
- }
-
- Vprevious;
- synchronized(this){
- previous=map.remove(key);
- if(previous!=null){
- size-=safeSizeOf(key,previous);
- }
- }
-
- if(previous!=null){
- entryRemoved(false,key,previous,null);
- }
-
- returnprevious;
- }
-
- /**
- *Calledforentriesthathavebeenevictedorremoved.Thismethodis
- *invokedwhenavalueisevictedtomakespace,removedbyacallto
- *{@link#remove},orreplacedbyacallto{@link#put}.Thedefault
- *implementationdoesnothing.
- *当item被回收或者删掉时调用。改方法当value被回收释放存储空间时被remove调用,
- * 或者替换item值时put调用,默认实现什么都没做。
- *<p>Themethodiscalledwithoutsynchronization:otherthreadsmay
- *accessthecachewhilethismethodisexecuting.
- *
- *@paramevictedtrueiftheentryisbeingremovedtomakespace,false
- *iftheremovalwascausedbya{@link#put}or{@link#remove}.
- * true---为释放空间被删除;false---put或remove导致
- *@paramnewValuethenewvaluefor{@codekey},ifitexists.Ifnon-null,
- *thisremovalwascausedbya{@link#put}.Otherwiseitwascausedby
- *anevictionora{@link#remove}.
- */
- protectedvoidentryRemoved(booleanevicted,Kkey,VoldValue,VnewValue){}
-
- /**
- *Calledafteracachemisstocomputeavalueforthecorrespondingkey.
- *Returnsthecomputedvalueornullifnovaluecanbecomputed.The
- *defaultimplementationreturnsnull.
- *当某Item丢失时会调用到,返回计算的相应的value或者null
- *<p>Themethodiscalledwithoutsynchronization:otherthreadsmay
- *accessthecachewhilethismethodisexecuting.
- *
- *<p>Ifavaluefor{@codekey}existsinthecachewhenthismethod
- *returns,thecreatedvaluewillbereleasedwith{@link#entryRemoved}
- *anddiscarded.Thiscanoccurwhenmultiplethreadsrequestthesamekey
- *atthesametime(causingmultiplevaluestobecreated),orwhenone
- *threadcalls{@link#put}whileanotheriscreatingavalueforthesame
- *key.
- */
- protectedVcreate(Kkey){
- returnnull;
- }
-
- privateintsafeSizeOf(Kkey,Vvalue){
- intresult=sizeOf(key,value);
- if(result<0){
- thrownewIllegalStateException("Negativesize:"+key+"="+value);
- }
- returnresult;
- }
-
- /**
- *Returnsthesizeoftheentryfor{@codekey}and{@codevalue}in
- *user-definedunits.Thedefaultimplementationreturns1sothatsize
- *isthenumberofentriesandmaxsizeisthemaximumnumberofentries.
- *返回用户定义的item的大小,默认返回1代表item的数量,最大size就是最大item值
- *<p>Anentry'ssizemustnotchangewhileitisinthecache.
- */
- protectedintsizeOf(Kkey,Vvalue){
- return1;
- }
-
- /**
- *Clearthecache,calling{@link#entryRemoved}oneachremovedentry.
- * 清空cacke
- */
- publicfinalvoidevictAll(){
- trimToSize(-1);//-1willevict0-sizedelements
- }
-
- /**
- *Forcachesthatdonotoverride{@link#sizeOf},thisreturnsthenumber
- *ofentriesinthecache.Forallothercaches,thisreturnsthesumof
- *thesizesoftheentriesinthiscache.
- */
- publicsynchronizedfinalintsize(){
- returnsize;
- }
-
- /**
- *Forcachesthatdonotoverride{@link#sizeOf},thisreturnsthemaximum
- *numberofentriesinthecache.Forallothercaches,thisreturnsthe
- *maximumsumofthesizesoftheentriesinthiscache.
- */
- publicsynchronizedfinalintmaxSize(){
- returnmaxSize;
- }
-
- /**
- *Returnsthenumberoftimes{@link#get}returnedavaluethatwas
- *alreadypresentinthecache.
- */
- publicsynchronizedfinalinthitCount(){
- returnhitCount;
- }
-
- /**
- *Returnsthenumberoftimes{@link#get}returnednullorrequiredanew
- *valuetobecreated.
- */
- publicsynchronizedfinalintmissCount(){
- returnmissCount;
- }
-
- /**
- *Returnsthenumberoftimes{@link#create(Object)}returnedavalue.
- */
- publicsynchronizedfinalintcreateCount(){
- returncreateCount;
- }
-
- /**
- *Returnsthenumberoftimes{@link#put}wascalled.
- */
- publicsynchronizedfinalintputCount(){
- returnputCount;
- }
-
- /**
- *Returnsthenumberofvaluesthathavebeenevicted.
- * 返回被回收的数量
- */
- publicsynchronizedfinalintevictionCount(){
- returnevictionCount;
- }
-
- /**
- *Returnsacopyofthecurrentcontentsofthecache,orderedfromleast
- *recentlyaccessedtomostrecentlyaccessed.返回当前cache的副本,从最近最少访问到最多访问
- */
- publicsynchronizedfinalMap<K,V>snapshot(){
- returnnewLinkedHashMap<K,V>(map);
- }
-
- @OverridepublicsynchronizedfinalStringtoString(){
- intaccesses=hitCount+missCount;
- inthitPercent=accesses!=0?(100*hitCount/accesses):0;
- returnString.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
- maxSize,hitCount,missCount,hitPercent);
- }
- }
分享到:
相关推荐
Android使用LruCache缓存图片,
android图片墙,解决oom 博客地址: http://blog.csdn.net/pangzaifei/article/details/37763753
基于Andoird的LRUCache机制介绍
AsyncTask的使用及ListView的常见优化 asyncTask异步加载数据 使用了LruCache优化图片加载 通过滑动监听提高ListView滑动流畅度.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习...
Android缓存的一个Demo,对Lrucache 和Srofrencen 进行了分析的使用,希望大家一起学习交流
Android Lrucache加载网络图片(AsyncTask ),采用Lrucache算法,AsyncTask 异步缓存加载图片
DiskLruCache需要导入的几个类,将这几个类一起copy到你的项目中,没有规定需要放在什么包(随便放),需要修改一下package name(改成你的包名)
android三级缓存的DiskLruCache类的代码以及其他使用到的工具类
LruCache 的使用 Demo,虽然加载了非常大的图片,但是使用了 Lrucache 作为缓存,使整个 app 的内存使用情况降下来了。
AndroidStudio利用DiskLruCache和LruCache实现简单的照片墙
此为示例代码,如对资源内容有疑问,可以到以下博客地址中留言: http://blog.csdn.net/guolin_blog/article/details/34093441
LruCache 什么是LruCache? LruCache实现原理是什么? 这两个问题其实可以作为一个问题来回答,知道了什么是 LruCache,就只然而然的知道 LruCache 的实现原理;Lru的全称是Least Recently Used ,近期最少使用的!...
在预览图片的时候容易造成oom,这时候用Lurcache和软应用,先在缓存或软应用或sd卡中加载图片,如果没有去网络中下载图片,然后把其添加到sd中同时也放入缓存中
PhotosWallDemo 结合LruCache和DiskLruCache PhotosWallDemo 结合LruCache和DiskLruCache
LruCache 源码,摘抄下来,方便查阅。 https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/util/LruCache.java
详解Android的内存优化–LruCache.zip
LruCache是基于Lru算法实现的一种缓存机制。本文对LruCache的概念和实现原理进行介绍,通过实例分析和使用介绍,让大家更好的了解LruCache,下面跟着小编一起来看下吧
Android之本地缓存——LruCache(内存缓存)与DiskLruCache(硬盘缓存)统一框架 [注:本内容来自网络,在此分享仅为帮助有需要的网友,如果侵犯了您的权利,麻烦联系我,我会第一时间删除,谢谢您。]
实现网络图片加载在手机客户端,保存到内存-SD卡-网络,三步走从而实现减小流量消耗,让用户体验跟家流畅