android:LruCache緩衝小結

來源:互聯網
上載者:User

標籤:android   style   blog   io   ar   color   os   使用   sp   

原理:

LruCache以索引值對的形式,初始化時,需要設定緩衝的大小K,超過這個大小的資料將會被清除。注意:清除的資料,是那些被先加入的資料。LruCache內部的資料結構是LinkedHashMap儲存的。這樣,LruCache就達到了緩衝最近put的K個資料。


使用:
[code]

int cacheSize = 4 * 1024 * 1024; // 4MiB   LruCache bitmapCache = new LruCache(cacheSize) {       protected int sizeOf(String key, Bitmap value) {           return value.getByteCount();          }}

注意,緩衝不同的資料,需要重寫sizeOf方法。比如,上面緩衝的是圖片。本質上,這些資料都是儲存在記憶體中的,因此,cacheSize不易過大。


LruCache原始碼:

import java.util.LinkedHashMap;import java.util.Map; public class LruCache<K, V> {    private final LinkedHashMap<K, V> map;     private int size;    private int maxSize;     private int putCount;    private int createCount;    private int evictionCount;    private int hitCount;    private int missCount;     public LruCache(int maxSize) {        if (maxSize <= 0) {            throw new IllegalArgumentException("maxSize <= 0");        }        this.maxSize = maxSize;        this.map = new LinkedHashMap<K, V>(0, 0.75f, true);    }     public final V get(K key) {        if (key == null) {            throw new NullPointerException("key == null");        }         V mapValue;        synchronized (this) {            mapValue = map.get(key);            if (mapValue != null) {                hitCount++;                return mapValue;            }            missCount++;        }         V createdValue = create(key);        if (createdValue == null) {            return null;        }         synchronized (this) {            createCount++;            mapValue = map.put(key, createdValue);             if (mapValue != null) {                // There was a conflict so undo that last put                map.put(key, mapValue);            } else {                size += safeSizeOf(key, createdValue);            }        }         if (mapValue != null) {            entryRemoved(false, key, createdValue, mapValue);            return mapValue;        } else {            trimToSize(maxSize);            return createdValue;        }    }     public final V put(K key, V value) {        if (key == null || value == null) {            throw new NullPointerException("key == null || value == null");        }         V previous;        synchronized (this) {            putCount++;            size += safeSizeOf(key, value);            previous = map.put(key, value);            if (previous != null) {                size -= safeSizeOf(key, previous);            }        }         if (previous != null) {            entryRemoved(false, key, previous, value);        }         trimToSize(maxSize);        return previous;    }     private void trimToSize(int maxSize) {        while (true) {            K key;            V value;            synchronized (this) {                if (size < 0 || (map.isEmpty() && size != 0)) {                    throw new IllegalStateException(getClass().getName()                            + ".sizeOf() is reporting inconsistent results!");                }                 if (size <= maxSize || map.isEmpty()) {                    break;                }                 Map.Entry<K, V> toEvict = map.entrySet().iterator().next();                key = toEvict.getKey();                value = toEvict.getValue();                map.remove(key);                size -= safeSizeOf(key, value);                evictionCount++;            }             entryRemoved(true, key, value, null);        }    }     public final V remove(K key) {        if (key == null) {            throw new NullPointerException("key == null");        }         V previous;        synchronized (this) {            previous = map.remove(key);            if (previous != null) {                size -= safeSizeOf(key, previous);            }        }         if (previous != null) {            entryRemoved(false, key, previous, null);        }         return previous;    }     protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue) {}     protected V create(K key) {        return null;    }     private int safeSizeOf(K key, V value) {        int result = sizeOf(key, value);        if (result < 0) {            throw new IllegalStateException("Negative size: " + key + "=" + value);        }        return result;    }     protected int sizeOf(K key, V value) {        return 1;    }     /**     * Clear the cache, calling {@link #entryRemoved} on each removed entry.     */    public final void evictAll() {        trimToSize(-1); // -1 will evict 0-sized elements    }     public synchronized final int size() {        return size;    }     public synchronized final int maxSize() {        return maxSize;    }     public synchronized final int hitCount() {        return hitCount;    }     public synchronized final int missCount() {        return missCount;    }     public synchronized final int createCount() {        return createCount;    }     /**     * Returns the number of times {@link #put} was called.     */    public synchronized final int putCount() {        return putCount;    }     /**     * Returns the number of values that have been evicted.     */    public synchronized final int evictionCount() {        return evictionCount;    }     /**     * Returns a copy of the current contents of the cache, ordered from least     * recently accessed to most recently accessed.     */    public synchronized final Map<K, V> snapshot() {        return new LinkedHashMap<K, V>(map);    }     @Override public synchronized final String toString() {        int accesses = hitCount + missCount;        int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0;        return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",                maxSize, hitCount, missCount, hitPercent);    }}


從原始碼中,我們可以清晰的看出LruCache的緩衝機制。


-------------------------------------------------------------------

更多交流,Android開發聯盟QQ群:272209595


android:LruCache緩衝小結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.