Android api level-22中android.support.v4.util.LruCache和android.util.LruCache的行为不一样问题

今天发现一个问题,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     }
View Code

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     }
View Code

 所以最好使用Support包中的LruCache。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。