有一段日子没有写博客了,放假的时候事情挺多的,最近又在啃android,以前写listview,或者其他图片显示过大总会发生oom的错误,找了点时间去看了android对于LruCache的支持,记录一下。
LruCache 缓存到底是什么,LRU是Least Recently Used 的缩写,翻译过来就是“最近最少使用”,LRU缓存就是使用这种原理实现,简单的说就是缓存一定量的数据,当超过设定的阈值时就把一些过期的数据删除掉,比如我们缓存100M的数据,当总数据小于100M时可以随意添加,当超过100M时就需要把新的数据添加进来,同时要把过期数据删除,以确保我们最大缓存100M。听了lrucache的作用,是不是很适合作为一种内存管理的方法呢可以看到构造方法中设置了最大的size同时创建了一个LinkedHashMap。
这里提供了一个通用的方法,当没有找到对应的key的entry的时候,提供了一个默认返回null的creat方法(同样可以通过重写该方法让creat可以创建具体的对象)
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++; } /* * Attempt to create a value. This may take a long time, and the map * may be different when create() returns. If a conflicting value was * added to the map while create() was working, we leave that value in * the map and release the created value. */ V createdValue = create(key); //如果没有找到,提供一种creat方法 if (createdValue == null) { //为空直接返回null return null; } synchronized (this) { createCount++; mapValue = map.put(key, createdValue); //创建了就要添加到map进去,尝试添加 if (mapValue != null) { //同样只有在替换掉entry时候才不会返回null // There was a conflict so undo that last put map.put(key, mapValue); //将mapValue添加 } else { size += safeSizeOf(key, createdValue); //已经将createdValue添加进去了,所以需要进行size添加 } } if (mapValue != null) { entryRemoved(false, key, createdValue, mapValue); return mapValue; } else { trimToSize(maxSize); //对size容量的检查,慢了就进行remove操作 return createdValue; } }可以看到get方法传入了key进行查找,如果找到就返回,同时默认返回空的creat方法,当creat被重写后,creat可能会耗时,同时createdValue可能会改变,同时可能会有put方法将新的同样的key的方法添加进去,所以后面会看到和put方法一样的操作。
同时trimToSize方法将会对溢出情况进行判断,移除最少使用的部分。