标签:
今天发现一个问题,ApiLevel-22的Android源码,两个版本的LruCache:android.support.v4.util.LruCache和android.util.LruCache在移除旧的缓存对象时的行为完全不一样。
android.support.v4.util.LruCache在移除缓存的时候是移除最近最少访问的,符合LruCache的设计初衷。
android.util.LruCache在缓存满了的情况下,会把当前加入的直接移除掉,不符合LruCache的设计初衷。
关键代码如下:
android.support.v4.util.LruCache,第15行代码
1 private void trimToSize(int maxSize) { 2 while (true) { 3 K key; 4 V value; 5 synchronized (this) { 6 if (size < 0 || (map.isEmpty() && size != 0)) { 7 throw new IllegalStateException(getClass().getName() 8 + ".sizeOf() is reporting inconsistent results!"); 9 } 10 11 if (size <= maxSize) { 12 break; 13 } 14 15 Map.Entry<K, V> toEvict = map.eldest(); 16 if (toEvict == null) { 17 break; 18 } 19 20 key = toEvict.getKey(); 21 value = toEvict.getValue(); 22 map.remove(key); 23 size -= safeSizeOf(key, value); 24 evictionCount++; 25 } 26 27 entryRemoved(true, key, value, null); 28 } 29 }
android.util.LruCache,第20行代码
1 private void trimToSize(int maxSize) { 2 while (true) { 3 K key; 4 V value; 5 synchronized (this) { 6 if (size < 0 || (map.isEmpty() && size != 0)) { 7 throw new IllegalStateException(getClass().getName() 8 + ".sizeOf() is reporting inconsistent results!"); 9 } 10 11 if (size <= maxSize) { 12 break; 13 } 14 15 // BEGIN LAYOUTLIB CHANGE 16 // get the last item in the linked list. 17 // This is not efficient, the goal here is to minimize the changes 18 // compared to the platform version. 19 Map.Entry<K, V> toEvict = null; 20 for (Map.Entry<K, V> entry : map.entrySet()) { 21 toEvict = entry; 22 } 23 // END LAYOUTLIB CHANGE 24 25 if (toEvict == null) { 26 break; 27 } 28 29 key = toEvict.getKey(); 30 value = toEvict.getValue(); 31 map.remove(key); 32 size -= safeSizeOf(key, value); 33 evictionCount++; 34 } 35 36 entryRemoved(true, key, value, null); 37 } 38 }
所以最好使用Support包中的LruCache。
Android api level-22中android.support.v4.util.LruCache和android.util.LruCache的行为不一样问题
标签:
原文地址:http://www.cnblogs.com/mayongsheng/p/4481675.html