DiskLruCache用于實(shí)現(xiàn)磁盤緩存烙如,它通過將緩存文件寫入文件系統(tǒng)實(shí)現(xiàn)緩存的效果爹袁。
使用前先添加依賴
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表示存儲(chǔ)媒體已掛載,并可以讀寫
Environment.getExternalStorageState()獲取外部存儲(chǔ)的狀態(tài)
isExternalStorageRemovable()表示外部存儲(chǔ)已經(jīng)被移除
如果外部可以儲(chǔ)存就存入/storage/emulated/0/Android/data/package_name/cache這個(gè)目錄
否則 存入/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()有四個(gè)參數(shù)刑桑,2.版本號(hào),3.單個(gè)節(jié)點(diǎn)對(duì)應(yīng)的數(shù)據(jù)個(gè)數(shù)募舟,4表示數(shù)據(jù)大小祠斧,如1024X1024X50表示50MB。
private String byteToHexString(byte[] bytes){
StringBuilder sb=new StringBuilder();
for(int i=0;i<bytes.length;i++){
String hex=Integer.toHexString(0xFF&bytes[i]);
if(hex.length()==1){
sb.append('0');
}
sb.append(hex);
}
return sb.toString();
}
該方法用于講byte轉(zhuǎn)換為16進(jìn)制拱礁,因?yàn)閖ava采用二進(jìn)制補(bǔ)碼琢锋,當(dāng)系統(tǒng)檢測(cè)到byte可能轉(zhuǎn)換成int(32位)或與int運(yùn)算,可能會(huì)對(duì)byte補(bǔ)1擴(kuò)充至32位呢灶,與0xff運(yùn)算使結(jié)構(gòu)不變吴超。
DiskLruche的緩存操作是通過Editor完成的,Editor便是緩存對(duì)象的編輯對(duì)象鸯乃。
通常來說可以用url的md5作為圖片的key鲸阻,url可能會(huì)有特殊字符,不易直接使用缨睡。
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()//如果發(fā)生異常遣臼,用來退回整個(gè)操作。
最后是緩存的讀取方法
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;
}