LRUCache具体使用

发布时间 2023-03-23 15:32:18作者: 懒懒初阳

LRUCache具体使用

LRU Cache是一种常见的缓存策略,通过最近最少使用的原则,在缓存满时考虑淘汰最近没有使用的数据。可以在Android中作为一个内存缓存工具使用,比如用于加载图片、网络请求等。

在Android中使用LRU Cache可以先创建一个继承自LruCache类的缓存类,重写其中的构造函数和以下3个方法:

  • sizeOf(Object key, Object value):返回指定 key-value 对在缓存中占用的内存大小。
  • entryRemoved(boolean evicted, K key, V oldValue, V newValue):当缓存元素被移除的时候会调用该函数,可以覆盖它以实现移除元素后的进一步操作。(可选)
  • create(size):该方法在元素未被找到时调用,可以重写它来提供这些对象的创造过程即从原仓库中获取数据并放入到新的缓存仓库中。如果返回 null 则代表外部创建对象并添加。

下面是一个简单的示例代码:

public class MemoryCache extends LruCache<String, Bitmap> {

    public MemoryCache(int maxSizeBytes) {
        super(maxSizeBytes);
    }

    // 重写 sizeOf 方法,计算每张图片所需要的内存空间大小
    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getByteCount();
    }

    // 当 LRU 算法决定把图片从缓存中删除时,就会回调此方法,此时我们需要将图片从内存中移除,否则会报 java.lang.IllegalStateException: Can't call remove on a recycled bitmap
    @Override
    protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
	     // Bitmap.isRecycled() 是一个 boolean 类型的方法,主要用于检查此位图是否已被回收。如果这个返回值为 true,则意味着当前的 Bitmap 对象已经无效了。 
        if (evicted && oldValue != null && !oldValue.isRecycled()) {
            oldValue.recycle();
        }
    }

    // 重写 create 方法,当 LRU 没有找到图片时自动调用此方法下载图片并加入缓存中
    @Override
    protected Bitmap create(String key) {
        Bitmap bitmap = 下载图片(key);
        if (bitmap == null) {
            bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.default_picture);
        } 
        return bitmap;
    }
}

使用时只需传入最大可用内存大小,然后按照普通 Map 的方式即可进行存取。例如,设置一个最大 4MB 大小的缓存:

MemoryCache memoryCache = new MemoryCache(4 * 1024 * 1024);
String imageUrl = "https://www.example.com/images/sample.png";
Bitmap bitmap = memoryCache.get(imageUrl); // 缓存读取
if(bitmap==null){
    // 不存在,则开始下载图片
    ImageLoader.loadImage(imageUrl,new ImageLoader.ActionListener(){
        @Override
        public void onSuccess(Bitmap bitmap){
            memoryCache.put(imageUrl,bitmap);// 存入缓存
        }
        @Override
        public void onFailure(){
            // onError处理
        }
    });
}