DiskLruCache基础

来源:互联网 发布:谷边由美 程序员 编辑:程序博客网 时间:2024/06/11 02:09

1、DiskLruCache基本概念

DiskLruCache并不是安卓原生的代码或者类,它是由Square团队开发的一个开源库,已经获得谷歌官方认证,可以放心使用,附上Git网址:

git 网址:https://github.com/JakeWharton/DiskLruCache

(题外话:square团队开发了很多的开源库,比如Retrofit,OkHttp,Picasso,LeakCanary,Dagger等知名开源库,附上开源库的简单介绍:http://blog.csdn.net/b10060224/article/details/50853668)

通过DiskLruCache可以非常方便地将我们的数据缓存到本地空间,优酷和今日头条用到的就是DiskLruCache来进行离线数据缓存

2、DiskLruCache用法

DiskLruCache常用的API:

1)、通过DiskLruCache.open去初始化一个缓存对象

2)、通过DiskLruCache.get(String key)去获取到对应Key下的缓存数据

3)、通过DiskLruCache.Editor对象将数据保存本地

还有很多其他的API,例如remove,removeAll,获取缓存使用空间方法,等等

3、使用时要注意的问题

1)、DiskLruCache是外部存储设备空间的缓存,所以使用的时候要判断有没有外部存储设备

有外置: /sdcard/Android/data/<application package>/cache

无外置:/data/data/Android/data/<application package>/cache

放在这两个目录下是为了当APP被卸载的时候这两个目录下对应的缓存数据也会被清空,不会造成相对应存储空间的浪费

2)、缓存文件时对key有特殊的要求

只能用英文字母(大小写)和数字来作为key


使用第三方库的时候一般建议使用外观模式对第三方类进行封装,降低代码与第三方库的耦合性,具体外观模式相关的知识可以参考一本书《Android源码设计模式》


代码讲解

工具类DiskLruCacheHelper:

package com.gn.violetapplication;import android.content.Context;import android.graphics.Bitmap;import android.util.Log;import com.jakewharton.disklrucache.DiskLruCache;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.io.BufferedWriter;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.OutputStreamWriter;/** * Created by violet on 2017/12/13. */public class DiskLruCacheHelper {    private static final String DIR_NAME = "diskCache"; //默认缓存文件夹名字    private static final int MAX_COUNT = 5*1024*1024;//默认缓存空间大小    private static final int DEFAUT_APP_VERSION = 1;//一旦版本升级,则所有缓存无效    private static final String TAG = "DiskLruCacheHelper";    private DiskLruCache mDiskLruCache; //gradle中添加compile 'com.jakewharton:disklrucache:2.0.2'    private DiskLruCache generateCache(Context context, File dir,int maxCount)throws IOException{        if(!dir.exists() || !dir.isDirectory()){ //判断文件是否合法            throw new IllegalArgumentException(dir+"is not a directory or does not exists.");        }        int appVersion = context == null ? DEFAUT_APP_VERSION : Utils.getAppVersion(context);        DiskLruCache diskLruCache = DiskLruCache.open(dir,appVersion,DEFAUT_APP_VERSION,maxCount); //通过open方法获得diskLruCache对象,对数据进行增删改查的操作        return diskLruCache;    }    /**     * 存储字符串的时候使用     * @param key     * @param value     */    public void put(String key,String value){        DiskLruCache.Editor edit = null;        BufferedWriter bw = null;        try{            edit = editor(key);            if(edit == null){                return;            }            OutputStream os = edit.newOutputStream(0);            bw = new BufferedWriter(new OutputStreamWriter(os));            bw.write(value);            edit.commit(); //write clean        }catch (IOException e){            e.printStackTrace();            try{                edit.abort(); //write remove            }catch (IOException el){                el.printStackTrace();            }        }finally {            try{                if(bw!=null){                    bw.close();                }            }catch (IOException e){                e.printStackTrace();            }        }    }    /**     * 获取对应key下的String值     * @param key     * @return     */    public String getAsString(String key){        InputStream inputStream = null;        try{            inputStream = get(key);            if(inputStream == null){                return null;            }            StringBuilder sb = new StringBuilder();            int len = 0;            byte[] buf = new byte[128];            while((len = inputStream.read(buf))!=-1){                sb.append(new String(buf,0,len));            }            return sb.toString();        }catch (IOException e){            e.printStackTrace();            if(inputStream!= null){                try{                    inputStream.close();                }catch (IOException el){                    el.printStackTrace();                }            }        }        return null;    }    public void put(String key, JSONObject jsonObject){        put(key,jsonObject.toString());    }    public JSONObject getJSonObject(String key){        String val = getAsString(key);        try{            if(val != null){                return new JSONObject(val);            }        }catch (JSONException e){            e.printStackTrace();        }        return null;    }    public void put(String key,JSONArray jsonArray){        put(key,jsonArray.toString());    }    public JSONArray getJSONArray(String key){        String JSONString = getAsString(key);        try{            JSONArray obj = new JSONArray(JSONString);            return obj;        }catch (JSONException e){            e.printStackTrace();        }        return null;    }    public void put(String key, Bitmap bitmap){        put(key,bitmap.toString());    }    public DiskLruCache.Editor editor(String key){        try{            DiskLruCache.Editor edit = mDiskLruCache.edit(key);            if(edit == null){                Log.w(TAG,"the entry spcified key:"+key+"is editing by other.");            }            return edit;        }catch(IOException e){            e.printStackTrace();        }        return null;    }    public InputStream get(String key){        DiskLruCache.Snapshot snapshot;  //快照对象        try{            snapshot = mDiskLruCache.get(Utils.hashKeyForDisk(key));            if(snapshot == null){                return snapshot.getInputStream(0);            }        }catch(IOException e){            e.printStackTrace();        }        return null;    }}


完善之前的缓存图片例子:

/** **用来加载网络图片,并缓存到本地和内存 */public class SimpleImageLoader{    private static SimpleImageLoader mLoader;    private LruCache<String,Bitmap> mLrucache;    private DiskLruCacheHelper mDiskLruCacheHelper;    public static SimpleImageLoader getInstance(){        if(mLoader ==  null){            synchronized (SimpleImageLoader.class){                if(mLoader == null){                    mLoader = new SimpleImageLoader();                }            }        }        return mLoader;    }    //用来初始化缓存对象    private SimpleImageLoader(){        //获取到最大可用的内存空间        int maxSize = (int)Runtime.getRuntime().maxMemory()/8;//一般用除以八来表示,具体视APP大小而定        mLrucache = new LruCache<String,Bitmap>(maxSize){            @Override            protected int sizeOf(String key, Bitmap value) {                return value.getByteCount();            }        };        mDiskLruCacheHelper = new DiskLruCacheHelper();    }    //用来加载网络图片    public void displayImage(ImageView view, String url){        //首先判断内存缓存中是否有这张图片        Bitmap bitmap = getBitmapFromCache(url);        if(bitmap != null){            view.setImageBitmap(bitmap);        }else{            downloadImage(view,url);        }    }    //从缓存中读取图片    private Bitmap getBitmapFromCache(String url){        if(url != null){            if(mLrucache.get(url) != null){                return mLrucache.get(url);            }            if(mDiskLruCacheHelper.get(url) != null){                return mDiskLruCacheHelper.getBitmap(url);            }        }        return null;    }    //将下载下来的图片保存到缓存中    private void putBitmapToCache(Bitmap bitmap,String url){        if(bitmap !=null){            mLrucache.put(url,bitmap);            mDiskLruCacheHelper.put(url,bitmap);        }    }    private void downloadImage(final ImageView imageView,final String url){        //从网络下载图片,下载成功后并保存在缓存中    }}