LRU cache in Android
23 Dec 2013
LRU cache
LRU cache is very convinient to manager a list of data which has a limit space requirement.
LRU cache managers an object list. Each time a valued is accessed, it is moved to the head of the list. When a value is put into the cache, the value at the end of the list may be evicted.
There are two kinds of LruCache in Android: LruCache
and DiskLruCache
, the fisrt can be used to manager an set of objects, the later can be used to manager files.
When to use
A scenario that a LruCache can be used is to manager the quota of disk cache and memory cache when loading a network image.
After an image is loaded from the remote server, commonly it will be writen to disk for further use. When the image is required to display in the ImageView
we will decode the bitmap data from this file. The decoding operation will take a long time. To avoid the same image to be decode for multiple time for the bitmap data, the bitmap data will be cached in the memory after the first time it is decoded.
But the memory and the storage space is very limited, we can not take too much of that. Each time a file is writen to storage of a bitmap data is cached into memory, we must check the total size of the cached data and remove the eldest objects if nessery.
Here, the LRU Cache
will make things easy.
Memory LruCache
LruCache
is in the support V4
package. It is very simple.
LRU cache
|
+- -map, LinkedHashmap
|
+- +put(K key, V value)
|
+- +get(K key)
|
+- -sizeOf(K key, V value)
|
+- -entryRemoved(K key,V value)
|
+- -create(K key)
The LruCache
has a LinkedHashmap
inside, which is constructed by
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
The third parameter allow the LinkedHashmap
to put the element to the head of the linked list after accessed, both by get
and set
.
sizeOf(K key, V value)
method return the size of each count which will be used to calculate the size of the whole size. > The default implementions returns 1, which make the LRU cache only manager a limit amount of objects.- The method
put(K key, V value)
cache the value to the cache and check the size. The method
get(K key)
will return the value for the key if it is exist in the cache.When a value is returned, it will move to the head of the queue, this is grantened by the
LinkedHashmap
;If the value is not exist, method
create(K key)
will be called to create the value. If a the value is created, it will be put into cache and the limit size will be checked. This will make the code simple.entryRemoved
will be call when an object is removed when the new value conrespong value of this key is put into cache or the total size of the cache has exceed the limit.
We can make a limit cache to store BitmapData:
int cacheSizeInKB = 1024 * 10; // 10MB
LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(cacheSizeInKB) {
@Override
protected void entryRemoved(boolean evicted, String key, Bitmap old, Bitmap new) {
}
/**
* Measure item size in kilobytes rather than units,
* which is more practical for a bitmap cache
*/
@Override
protected int sizeOf(String key, Bitmap value) {
final int bitmapSize = value.getByteCount() / 1024;
return bitmapSize == 0 ? 1 : bitmapSize;
}
};
DiskLurCache
The DiskLruCache
has an implementaion in JB source.
DiskLruCache
|
+- +get() // return a snapshot which is realted to the key.
|
+- +edit() // return the default `Editor` related the an `Entry` which is related to the key.
Like LruCache
, it has a LinkedHashmap
inside to manage the access order of the cached files.
There are some classes where are used to managed the info of the cached files:
Editor
Snapshot
Entry
Follow Me on GitHub