美文网首页
DiskLruCache+LruCache

DiskLruCache+LruCache

作者: Android刘东 | 来源:发表于2020-05-29 11:16 被阅读0次

LruCache保存中在运行内存 LruCache用法


import android.graphics.Bitmap;

import java.util.Iterator;

public class MyLruCache {
    static android.util.LruCache<String, Bitmap> cache;

    static {
        int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        //2.分配缓存的大小
        int cacheSize = 1 * 1024 * 1024;// 1MiB 根据业务需要
        //3.创建LruCache对象并重写 sizeOf 方法
        cache = new android.util.LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
//重写sizeOf方法,返回图片的占用字节数而不是图片的个数,每次添加图片是会被调用
                //转换成KB,sizeOf完成Bitmap对象的大小计算
                return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
            }
        };
    }


    //4.从缓存中读取图片
    public static Bitmap getBitmapfromCache(String url) {
        synchronized (cache) {
            return cache.get(url);
        }
    }
    public static boolean contains(String url) {
        if (cache.get(url) != null) {
            return true;
        } else {
            return false;
        }
    }

    //5.将下载的图片保存在缓存中
    public static void putBitmaptoCache(Bitmap bitmap, String url) {
        synchronized (cache) {
            if (cache.get(url) == null && bitmap != null) {
                cache.put(url, bitmap);
            }
        }
    }
}

LRU算法

新数据插入到链表头部;所以DiskLruCache+LruCache都用到了LinkedHashMap
每当缓存命中(即缓存数据被访问),则将数据移到链表头部;
当链表满的时候,将链表尾部的数据丢弃。
当存在热点数据时,LRU的效率很好,但偶发性的、周期性的批量操作会导致LRU命中率急剧下降,缓存污染情况比较严重。
命中时需要遍历链表,找到命中的数据块索引,然后需要将数据移到头部

DiskLruCache 磁盘缓存

需要导入第三方
https://github.com/JakeWharton/DiskLruCache
常用方法:

1.获得对象DiskLruCache.open
2.编辑DiskLruCache.edit获得DiskLruCache.Editor对象
DiskLruCache.Editor.newOutputStream 输入流
通过输入流写入数据
保存DiskLruCache.Edito.comit:
  public void commit() throws IOException {
            if (hasErrors) {
                completeEdit(this, false);
                remove(entry.key); // The previous entry is stale.
            } else {
                completeEdit(this, true);
            }
            committed = true;
        }
    private synchronized void completeEdit(DiskLruCache.Editor editor, boolean success) throws IOException {
        journalWriter.flush();
    }
 这是个同步日志journal文件
 cache.journalWriter = new BufferedWriter(
                        new OutputStreamWriter(new FileOutputStream(cache.journalFile, true), Util.US_ASCII));

3.flush()会判断 不够大小移除 
private void trimToSize() throws IOException {
        while (size > maxSize) {
            Map.Entry<String, DiskLruCache.Entry> toEvict = lruEntries.entrySet().iterator().next();
            remove(toEvict.getKey());
        }
    }

相关文章

  • DiskLruCache+LruCache

    LruCache保存中在运行内存 LruCache用法 LRU算法 DiskLruCache 磁盘缓存 需要导入第...

网友评论

      本文标题:DiskLruCache+LruCache

      本文链接:https://www.haomeiwen.com/subject/pkhxzhtx.html