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;
}