美文网首页Android知识Android开发
LruCache + File 图片缓存笔记

LruCache + File 图片缓存笔记

作者: chauI | 来源:发表于2016-11-14 14:53 被阅读146次
    • 三级缓存
    • Lrucache
    • File

    三级缓存,第一级是内存缓存,第二级是文件缓存,第三级是网络缓存。
    针对于图片的一个缓冲机制

    LruCache 详解

    LruCache 选择的数据结构是 LinkedHashMap,一个 util 包中的双向循环链表。
    每当我们更新(即调用 put 方法)或访问(即调用 get 方法)map 中的结点时,LinkedHashMap 内部都会将这个结点移动到链表的尾部,
    因此,在链表的尾部是最近刚刚使用的结点,所以当我们的缓存空间不足时,就应该持续把链表头部结点移除掉,直到有剩余空间放置新结点。

    • 初始化 Lrucache 对象
      通过获取到程序可用的内存,适当的控制缓存的大小。
      实际中,通常通过重写 Application 类的方法来实现全局范围内获取该变量。
    final int cachesize = (ActivityManager)getSystemService(
                               Context.ACTIVITY_SERVICE)).getMemoryClass();
    LruCache myLruCache = new LruCache<String,Bitmap>(cachesize){
        protected int sizeOf(String key,Bitmap bitmap){
            return bitmap.getByteCount()/1024;
        }
    }
    
    • 添加缓存操作
      添加语句Put:myLruCache.put(string,bitmap)
      通常会先判断文件是否已经在缓存中存在,
      如果存在,会 覆盖原来的数据,并返回旧的数据。

    • 在缓存中读取文件
      读取语句:myLruCache.get(string);

      /**
        * @description 将bitmap添加到内存中去
        *
        * @param key
        * @param bitmap
        */
        public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
            if (getBitmapFromMemCache(key) == null) {
                mMemoryCache.put(key, bitmap);
            }
        }
      /**
        * @description 通过key来从内存缓存中获得bitmap对象
        *
        * @param key
        * @return
        */
        private Bitmap getBitmapFromMemCache(String key) {
            return mMemoryCache.get(key);
        }
    
    • 节点被删除时的回调方法
      entryRemoved() 是一个可以被重写的空方法,
    protected void entryRemoved(boolean evicted, K key, V oldValue, V newValue)
    

    在节点数据被移除的时候被调用
    包括手动 remove、put 操作中被覆盖、到达缓存上限被移除,都可以通过这个方法进行资源的回收等操作

    • 根据 maxSize 清理缓存
      trimToSize 在每次 put 操作都会执行一次,这时候的 maxSize 等于我们在初始化 LruCache 时传入的数值
    public void trimToSize(int maxSize)
    

    但我们也可以手动调用这个方法设置一个临时的 maxSize 来清理缓存

    • 对重写 sizeOf() 的说明:
      初始化 LruCache 的时候需要重写 sizeOf(),因为 LruCache 允许存入不同类型的对象,而对象的类型不同,测量大小的方法也是不一样的。
    bitmap.getByteCount();
    bitmap.getRowBytes() * bitmap.getHeight(); //兼容低版本
    string.length();
    stringList.length;
    

    但也有这种:

    return bitmap.getByteCount() / 1024;//返回了图片的数量
    

    这种情况,见过几次不推荐

    File

    LruCache 将图片保存在缓存中,适合不需要保存太久或者实时更新的文件和数据。
    File 是java中 io 下的一个类,在系统中创建一个文件来保存数据。

    /**
    * 二建缓存,读取bitmap的操作
    * @param path
    * @return
    */
    private Bitmap fromSecondCaush(String path){
        String fileName=path.substring(path.lastIndexOf("/")+1);
        String filePath=context.getExternalFilesDir(null)+"/"+fileName;
        File file=new File(filePath);
        if(file.exists()){
            return BitmapFactory.decodeFile(file.getAbsolutePath());
        }
        return null;
    }
    /**
    * 二级缓存,保存的操作
    * @param path
    * @throws IOException
    */
    private Bitmap putSecondCaush(String path,Bitmap bitmap) throws IOException {
        String fileName=path.substring(path.lastIndexOf("/")+1);
        String filePath=context.getExternalFilesDir(null)+"/"+fileName;
        FileOutputStream fos = new FileOutputStream(filePath);
        //将 bitmap 质量压缩至 path
        bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
        fos.close();
        return bitmap;
    }
    

    context.getExternalFilesDir();
    获取到 SDCard/Android/data/"应用包名"/files/目录,一般在该目录下放一些长时间保存的数据。
    context.getExternalCacheDir();
    获取到 SDCard/Android/data/"应用包名"/cache/目录,一般在该目录下放一些临时的缓存数据。

    所以fileName就是保存的文件名,filePath是文件保存的目录。

    相关文章

      网友评论

        本文标题:LruCache + File 图片缓存笔记

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