Android使用DiskLruCache进行数据缓存

1. 按照惯例先来代码传送门DiskLruCacheDemo

2. 效果图

效果图

3. DiskLruCache简介

DiskLruCache是JakeWharton大神的杰作,它采用的是LRU算法,通过LRU算法对缓存进行管理,以最近最少使用作为管理的依据,删除最近最少使用的数据,保留最近最常用的数据

4. DiskLruCache使用

4.1 DiskLruCache虽然得到Google认证,但是SDK中还没有加入,所以使用时需要我们手动添加依赖

compile ‘com.jakewharton:disklrucache:2.0.2’?

4.2 创建DiskLruCache对象
4.2.1 DiskLruCache不能通过构造方法来创建,它通过open方法来创建自身。
 try {
            if (mDiskLurCache != null) {
                mDiskLurCache.close();
                mDiskLurCache = null;
            }
            int appVersionCode = getAppVersionCode(mContext);
            File cacheFile = getCacheFile(mContext, fileName);

            mDiskLurCache = DiskLruCache.open(cacheFile, appVersionCode, 1, CACHE_MAXSIZE);
        } catch (IOException e) {

        }

参数说明
1. directory 数据缓存地址
2. appVersion 版本号,当版本号改变数据会被清除
3. valueCount:同一个key可以对应多少文件
4. maxSize:最大可以缓存的数据量

4.2.2 设置DiskLruCache的存储路径
    private File getCacheFile(Context context, String fileName) {

        String cachePath = "";
        //判读sd卡是否可用
        if ((Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable())
                && context.getExternalCacheDir() != null) {

            //获取有sd卡时的路径,该路径在程序卸载时会被删除
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            //获取无sd卡时的路径,该路径在程序卸载时会被删除
            cachePath = context.getCacheDir().getPath();
        }
        //File.separator 分隔符
        return new File(cachePath + File.separator + fileName);
    }

设置DiskLruCache的存储路径时需要对sd卡可用进行判断,并且路径和我们的程序相关,程序卸载时该路径下的文件就会被删除

4.2.3 其他参数就不多说了
4.3 数据缓存进磁盘

这里缓存DiskLruCache.Editor对象来进行数据缓存

        if (mDiskLurCache != null) {
            try {
                String md5Key = getMD5(key);
                DiskLruCache.Editor edit = mDiskLurCache.edit(md5Key);
                return edit;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

这里和SharedPreferences存数据相似,注意一点的是key需要加密,我用的是MD5的方式进行加密
获取到Editor之后就需要用流对数据进行写入,这里不多说了直接贴代码

 public void put(String key, Object object) {
        ObjectOutputStream oos = null;
        DiskLruCache.Editor editor = null;
        OutputStream outputStream = null;
        try {
            editor = editor(key);
            if (editor == null) {
                return;
            }
            outputStream = editor.newOutputStream(0);
            oos = new ObjectOutputStream(outputStream);
            oos.writeObject(object);
            oos.flush();
            editor.commit();
        } catch (IOException e) {
            e.printStackTrace();
            try {
                if (editor != null)
                    editor.abort();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {


            }
        }
    }

上面的代码是存入Object类型的数据,需要注意的是我们在存的时候要对该类进行序列话操作,不然存入的数据就会为空

 public void put(String key, String value) {
        DiskLruCache.Editor editor = null;
        BufferedWriter writer = null;
        OutputStream os = null;
        try {
            editor = editor(key);
            if (editor == null) {
                return;
            }
            os = editor.newOutputStream(0);
            writer = new BufferedWriter(new OutputStreamWriter(os));
            writer.write(value);
            writer.flush();
            editor.commit();
        } catch (IOException e) {
            e.printStackTrace();
            try {
                if (editor != null)
                    editor.abort();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

上面代码是存入String类型的数据

4.4 从磁盘中读取数据

读取数据需要 DiskLruCache.Snapshot对象,直接贴代码

    public DiskLruCache.Snapshot snapshot(String key) {

        String md5Key = getMD5(key);
        if (mDiskLurCache != null) {
            try {
                DiskLruCache.Snapshot snapshot = mDiskLurCache.get(md5Key);
                return snapshot;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

获取到DiskLruCache.Snapshot之后,通过DiskLruCache.Snapshot对象获取InputStream

    private InputStream getInputStream(String key) {
        DiskLruCache.Snapshot snapshot = snapshot(key);
        if (snapshot == null) {
            return null;
        }
        InputStream inputStream = snapshot.getInputStream(0);
        return inputStream;
    }

然后通过InputStream读取数据

    public <T> T getObjectCache(String key) {
        InputStream inputStream = getInputStream(key);
        ObjectInputStream ois = null;
        T object = null;
        if (inputStream == null) {
            return null;
        }
        try {
            ois = new ObjectInputStream(inputStream);
            object = (T) ois.readObject();
            return object;
        } catch (Exception e) {
            e.printStackTrace();

        } finally {

            try {
                if (ois != null) {
                    ois.close();
                }
            } catch (IOException e) {

            }

            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return null;
    }

读取Object类型数据。


    public String getStringCache(String key) {
        InputStream inputStream = getInputStream(key);
        InputStreamReader inputStreamReader = null;
        BufferedReader in = null;
        if (inputStream == null) {
            return null;
        }

        try {
            inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            in = new BufferedReader(inputStreamReader);
            StringBuilder buffer = new StringBuilder();
            String line;
            try {
                while ((line = in.readLine()) != null) {
                    buffer.append(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return buffer.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();

        } finally {
            try {
                if (in != null)
                    in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if (inputStreamReader != null)
                    inputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if (inputStream != null)
                    inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;

    }

读取String类型数据

5. 工具类的使用

1.创建对象

DiskLruCacheUtil mDiskLruCacheUtil = new DiskLruCacheUtil(this,"DISK_LRU_CACHE");

第二个参数就是文件名了

2.存数据

mDiskLruCacheUtil.put("STRING","我是string类型"); 
mDiskLruCacheUtil.put("object",userBean);
  1. 读数据
String string = mDiskLruCacheUtil.getStringCache("STRING");
UserBean userBean =mDiskLruCacheUtil.getObjectCache("object");

6. 结语

有了工具类数据缓存就会变得非常简单,最后祝各位生活愉快
最后代码传送门DiskLruCacheDemo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值