The previous two blogs wrote the file cache, now say Android-universal-image-loader's memory cache, the memory cache involves the class
The inheritance relationships for these classes are as follows:
Like a file cache, the memory cache involves two interfaces: Memorycacheaware and MemoryCache, where MemoryCache simply inherits Memorycacheaware and does not declare other methods. The Memorycacheaware interface method is as follows:
@Deprecatedpublic interface Memorycacheaware<k, v> {/** * puts value in the cache according to the key value * @return Returns True if the cache succeeds and returns false instead * /boolean put (k key, V value),/** gets the data from the cache based on key, returns null*/v get (k key) without relevant data,/** removes data from the cache based on key */void remove (k key);/** Returns all keys in the cache */collection<k> keys ();/** empties the Cache */void clear ();}
Here is a detailed description of how these caches work and how they are implemented, starting with Basememorycache and its subclasses
Basememorycache:
The class is an abstract class that provides a map for caching weak references to bitmap:
Private final map<string, reference<bitmap>> softmap = Collections.synchronizedmap (New hashmap<string, Reference<bitmap>> ());
Where the value field of Softmap is the reference type that holds the Bimmap, because reference is divided into strong references, weak references, soft references, and virtual references, this class also provides an abstract method Createreference (Bitmap value) Let subclasses rewrite and return different application types according to different requirements. The abstract method is to convert bitmap to a reference, which is called when the put method of Basememorycache is called.
/** creates a weak reference object based on value, which is an abstract class for subclasses to implement */protected abstract reference<bitmap> createreference (Bitmap value); @Override public boolean put (String key, Bitmap value) {softmap.put (Key, Createreference (value)); return true; }
Limitedmemorycache:
The class is an abstract class, inherits the Basememorychache, and has two restrictions on caching:
1) Limit the maximum value for each cached picture: Use SizeLimit as Peugeot, and call the parent class's put method to save the weak reference to the bitmap object that is larger than the sizelimit size. Otherwise, when the weak reference is saved, the strong reference of the bitmap object is cached with the type LinkedList variable hardcache .
2) also use SizeLimit to limit the size of the entire cache. The limit on whether to exceed the cache size will be judged when the put method is called, and if the cache size exceeds the limit to remove the corresponding bitmap object from LinkedList, the specific deletion policy has an abstract method of that class Remoenext () to implement in a child parent class (for example, one that deletes the largest BitMap , as well as under FIFO algorithm deletion, etc.), which is the typical application of template method patterns. The specific template method is romovenext () and getsize () are implemented by the corresponding subclasses.
Note that the return value of the Put method returns False if the size of the bitmap to be added exceeds SizeLimit, otherwise true (call the Put method in the subclass and return true to indicate that the cache was deleted)
Private final list<bitmap> Hardcache = collections.synchronizedlist (New linkedlist<bitmap> ()); <span style= "COLOR: #0000C0;" >//hardcache</span><span style= "color: #0000C0;" > is only used in this class to cache whether it is more than </span><span style= "color: #0000C0;" >sizelimit</span><span style= "color: #0000C0;" > Make judgments. </span>//bitmap put Cache @overridepublic Boolean put (String key, Bitmap value) {Boolean putsuccessfully = false;//Try to The add value to hard Cache//getsize method is an abstract method that implements an int valuesize = GetSize (value) in a subclass; int sizeLimit = This.sizelimit;int Curcachesi Ze = Cachesize.get ();//When the size of the bitmap is smaller than the size of the SizeLimit if (Valuesize < SizeLimit) {//deletes the cache to no more than the siezelimit limit. We while (curcachesize + valuesize > SizeLimit) {Bitmap removedvalue = Removenext ();//removenext () is an abstract method, Different delete policies are provided by different subclasses if (Hardcache.remove (Removedvalue)) {curcachesize = Cachesize.addandget (-getsize (Removedvalue));}} Put cache Hardcache.add (value);//Set Cache size Cachesize.addandget (valuesize);p utsuccessfully = true;} Get BITMThe size of the AP protected abstract int getsize (Bitmap value); Template method, by the corresponding subclass to implement the specific deletion strategy protected abstract Bitmap removenext ();
Largesetlimitedmemorycache:
The class is a subclass of Limitedmemorycache, which is designed to delete the largest bitmap object in the cache when the cache size limit is exceeded. The class implements two abstract methods of the parent class: GetSize () and Removenext () to get the size of a bitmap and delete the largest bitmap object.
The principle of implementation: This class adds a map variable, which is used to hold the bitmap object, while the corresponding value holds the size of the bitmap.
Private final Map<bitmap, integer> valuesizes = Collections.synchronizedmap (New Hashmap<bitmap, Integer> () );
Specific Removenext () implementations:
/** * loops through valuesizes and gets the largest Bitmap, and the returned Bimmap object that is removed from the map is passed to the parent class Hardcache Delete */@Overrideprotected Bitmap Remo Venext () {Integer maxSize = null; Bitmap largestvalue = null; Set<entry<bitmap, integer>> entries = Valuesizes.entryset (); synchronized (valuesizes) {for (entry< Bitmap, integer> entry:entries) {if (Largestvalue = = null) {Largestvalue = Entry.getkey (); maxSize = Entry.getvalue (); } else {Integer size = Entry.getvalue (); if (Size > maxSize) {maxSize = Size;largestvalue = Entry.getkey ();}}}} Perform deletion of rice as valuesizes.remove (largestvalue); return largestvalue;} Ways to get GetSize @Override protected int getsize (Bitmap value) { return Value.getrowbytes () * Value.getheight (); } @Override protected reference& Lt Bitmap> createreference (Bitmap value) { return New Weakreference<bitmap > (value); }
Delete operation Execution time: Call parent class put method is Execute
<span style= "FONT-SIZE:12PX;" > @Overridepublic boolean put (String key, Bitmap value) {if (Super.put (key, value)) {//If the method of the parent class is empty, Indicates that the size of the cache does not exceed the limit valuesizes.put (value, GetSize (value)); return true;} else {//the size of the cache exceeds the limit return false;}} </span>
Fifolimitedmemorycache:
Limitedmomroycache subclasses, when the size of the current cache exceeds the limit, the bitmap cache object of the response is deleted according to the FIFO (first-in-a-out) algorithm. This class uses LinkedList as a FIFO implementation, and when the cache size is exceeded, call Removenext () to remove the bitmap object that was first added to the cache. The corresponding method is as follows:
Implementation principle: Provides a linkedlist to save the bitmap object
Private final list<bitmap> queue = collections.synchronizedlist (new linkedlist<bitmap> ());
The specific Removenext () method is implemented:
@Overrideprotected Bitmap Removenext () {return queue.remove (0);} @Overrideprotected reference<bitmap> createreference (Bitmap value) {return new weakreference<bitmap> ( value);} @Overrideprotected int GetSize (Bitmap value) {return value.getrowbytes () * Value.getheight ();
Delete operation Execution time: Call parent class put method is Execute
@Overridepublic Boolean put (String key, Bitmap value) {if (Super.put (key, value)) {//If the cache is not out of range queue.add (value);// Put bitmap into queue return true;} else {//cache out of range return false;}}
Lrulimitedmemorycache:
The Limitedmemorycache subclass, which has not used the cache for the longest time, removes the most recently unused bitmap cache object from the cache when the cache size exceeds the SizeLimit limit.
Implementation principle: Provides a linkedhashmap to save the object, to achieve the effect of LRU
/** Cache providing least-recently-used logic */private final map<string, bitmap> lruCache = Collections.synchroniz Edmap (New linkedhashmap<string, bitmap> (initial_capacity, Load_factor, true));
The specific Removenext () method is implemented:
@Overrideprotected Bitmap Removenext () {return queue.remove (0);} @Overrideprotected reference<bitmap> createreference (Bitmap value) {return new weakreference<bitmap> ( value);} @Overrideprotected int GetSize (Bitmap value) {return value.getrowbytes () * Value.getheight ();
Delete operation Execution time: Call parent class put method is Execute
@Overridepublic Boolean put (String key, Bitmap value) {if (Super.put (key, value)) {//If the cache is not out of range queue.add (value);// Put bitmap into queue return true;} else {//cache out of range return false;}}
Usingfreqlimitedmemorycache:
A subclass of Limitedmemorycache that deletes the oldest unused bitmap object when the cache size exceeds sizelimit (that is, deletes the least-used bitmap)
Implementation principle: Provides a hashmap, the map key to save the bitmap object, and value to save the corresponding bitmap the number of uses
Private final Map<bitmap, integer> usingcounts = Collections.synchronizedmap (New Hashmap<bitmap, Integer> ( ));
When the get (string key) method is called to get bitmap, the bitmap uses the number of +1 operations
@Overridepublic Bitmap get (String key) {Bitmap value = Super.get (key);//Increment usage count for value if value is Conta ined in Hardcaheif (value = null) {Integer Usagecount = usingcounts.get (value), if (usagecount! = null) {//Usage +1usingcoun Ts.put (value, Usagecount + 1);}} return value;}
The specific Removenext () Implementation method:
@Overrideprotected int GetSize (Bitmap value) {return value.getrowbytes () * Value.getheight (); @Overrideprotected Bitmap Removenext () {Integer minusagecount = null; Bitmap leastusedvalue = null; Set<entry<bitmap, integer>> entries = Usingcounts.entryset (); synchronized (usingcounts) {for (entry< Bitmap, integer> entry:entries) {if (Leastusedvalue = = null) {Leastusedvalue = Entry.getkey (); minusagecount = ENTRY.G Etvalue ();} else {Integer lastvalueusage = Entry.getvalue (); if (Lastvalueusage < minusagecount) {minusagecount = Lastvalueusage; Leastusedvalue = Entry.getkey ();}}} Usingcounts.remove (Leastusedvalue); return leastusedvalue;} @Overrideprotected reference<bitmap> createreference (Bitmap value) {return new weakreference<bitmap> ( value);}
Delete operation Execution time: Call parent class put method is Execute
@Overridepublic Boolean put (String key, Bitmap value) {if (Super.put (key, value)) {usingcounts.put (value, 0); return true; } else {return false;}}
Limitedagememorycache:
To delete a cache object that exceeds the time limit, the implementation of this class is simple after all, the code is as follows:
public class Limitedagememorycache implements MemoryCache {private final memorycache cache;private final long Maxage;priv Ate final map<string, long> loadingdates = Collections.synchronizedmap (New hashmap<string, Long> ());/** * @ param Cache Wrapped Memory Cache * @param maxAge Max Object Age <b> (in seconds) </b>. If object age would exceed this value then it's 'll removed from the cache on next treatment (and therefore be Reloaded). */public Limitedagememorycache (memorycache cache, long maxAge) {This.cache = Cache;this.maxage = MaxAge *;//To Mill Iseconds} @Overridepublic Boolean put (String key, Bitmap value) {Boolean putsuccesfully = Cache.put (key, value); if (putsuc cesfully) {loadingdates.put (key, System.currenttimemillis ());} return putsuccesfully;} @Overridepublic Bitmap get (String key) {Long loadingdate = Loadingdates.get (key); Determine if timeout if (loadingdate! = null && system.currenttimemillis ()-loadingdate > mAxage) {cache.remove (key); Loadingdates.remove (key);} return Cache.get (key);} @Overridepublic void Remove (String key) {cache.remove (key); Loadingdates.remove (key);} @Overridepublic collection<string> keys () {return Cache.keys ();} @Overridepublic void Clear () {cache.clear (); Loadingdates.clear ();}}
Fuzzykeymemorycache:
The purpose of this cache is if there is one in the cache Key and to join the keytemp is removed from the cache, the Key point to the Bitmap object, and then put the new Key The object is added to the cache. The specific logic is as follows:
@Overridepublic Boolean put (String key, Bitmap value) {//Search equal key and remove this entrysynchronized (cache) {Stri ng Keytoremove = null;for (String cacheKey:cache.keys ()) {//determines if the corresponding key exists in the cache, and if it exists, delete if (Keycomparator.compare (Key, CacheKey) = = 0) {keytoremove = Cachekey;break;}} if (keytoremove! = null) {cache.remove (keytoremove);}} Return Cache.put (key, value);}
Lrumemorycache:
Another recently the longest unused cache, here is not much to say, directly paste code:
@Overridepublic Final Boolean put (String key, Bitmap value) {synchronized (this) {size = SizeOf (key, value); Bitmap previous = Map.put (key, value), if (previous! = null) {size = SizeOf (key, previous);}} Cache slimming, remove the most recent unused bitmap trimtosize (maxSize); return true;} private void trimtosize (int maxSize) {while (true) {String key; Bitmap value; Synchronized (this) {map.entry<string, bitmap> toevict = Map.entryset (). iterator (). Next (); if (toevict = = null) { break;} Key = Toevict.getkey (); value = Toevict.getvalue (); Map.Remove (key); size = SizeOf (key, value);}}