Android-DiskLruCache

DiskLruCache用于实现磁盘缓存,它通过将缓存文件写入文件系统实现缓存的效果。
使用前先添加依赖

implementation 'com.jakewharton:disklrucache:2.0.2'
public static File getDiskCacheDir() {
        String State=Environment.MEDIA_MOUNTED;
        if(State.equals(Environment.getExternalStorageState())||!isExternalStorageRemovable()){
            return new File(mContext.getExternalCacheDir().getPath()+File.separator+"BitmapCache");
        }else{
            return new File(mContext.getCacheDir().getPath()+File.separator+"BitmapCache");
        }
    }

该方法用于获取缓存目录
Environment.MEDIA_MOUNTED表示存储媒体已挂载,并可以读写
Environment.getExternalStorageState()获取外部存储的状态
isExternalStorageRemovable()表示外部存储已经被移除
如果外部可以储存就存入/storage/emulated/0/Android/data/package_name/cache这个目录
否则 存入/data/data/package_name/cache。

首先是初始化

File cacheDir=getDiskCacheDir();
        if(!cacheDir.exists()){
            cacheDir.mkdirs();
        }
        try {
            mDiskLruCache=DiskLruCache.open(cacheDir,1,1,1024*1024*50);
        } catch (IOException e) {
            e.printStackTrace();
        }

DiskLruCache.open()有四个参数,2.版本号,3.单个节点对应的数据个数,4表示数据大小,如1024X1024X50表示50MB。

private String byteToHexString(byte[] bytes){
        StringBuilder sb=new StringBuilder();
        for(int i=0;i

该方法用于讲byte转换为16进制,因为java采用二进制补码,当系统检测到byte可能转换成int(32位)或与int运算,可能会对byte补1扩充至32位,与0xff运算使结构不变。

DiskLruche的缓存操作是通过Editor完成的,Editor便是缓存对象的编辑对象。
通常来说可以用url的md5作为图片的key,url可能会有特殊字符,不易直接使用。

private String hashKeyFormUrl(String url){
        String cacheKey=null;
        try {
            final MessageDigest mDigest=MessageDigest.getInstance("MD5");
            mDigest.update(url.getBytes());
            cacheKey=byteToHexString(mDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return cacheKey;
    }

MessageDigest用于提供信息摘要算法功能,有MD5和SHA,MD5用于确保信息传输完整一致。

String uriStr=editText.getText().toString();
                        String key=hashKeyFormUrl(uriStr);
                        try {
                            DiskLruCache.Editor editor=mDiskLruCache.edit(key);
                            if(editor!=null){
                                OutputStream out=editor.newOutputStream(0);
                                if(downloadUrlToString(uriStr,out)){
                                    editor.commit();
                                }else{
                                    editor.abort();
                                }
                                mDiskLruCache.flush();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

editor.newOutputStream(DISK_CACHE_INDEX);用于获取文件输出流

下载操作

public boolean downloadUrlToString(String url, OutputStream out){
        HttpURLConnection connection=null;
        BufferedInputStream bin=null;
        BufferedOutputStream bout=null;

        try {
            final URL fUrl=new URL(url);
            connection=(HttpURLConnection)fUrl.openConnection();
            bin=new BufferedInputStream(connection.getInputStream());
            bout=new BufferedOutputStream(out);
            int b;
            while((b=bin.read())!=-1){
                bout.write(b);
            }
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(connection!=null){
                connection.disconnect();
            }
            try {
                if(bin!=null)
                bin.close();
                if(bout!=null)
                bout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }return false;
    }
editor.commit()//最后需要通过commit()来提供写入操作
editor.abort()//如果发生异常,用来退回整个操作。

最后是缓存的读取方法

private Bitmap getBitmapFromCache(String urlStr){
        String key=hashKeyFormUrl(urlStr);
        try {
            DiskLruCache.Snapshot snapshot=mDiskLruCache.get(key);
            if(snapshot!=null){
                InputStream in=snapshot.getInputStream(0);
                return BitmapFactory.decodeStream(in);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

你可能感兴趣的:(Android-DiskLruCache)