ImageLoader LruCache DisLruCache 雙緩存
緩存?
內存緩存跟磁盤緩存,有這種一個概念,當第一次加載完數據之后保存到內存或者磁盤,當再次讀取的時候。我們就可以>先去讀硬盤里面的緩存,如果沒有則讀內存;如果在沒有則去加載網絡請求;
為何要雙緩存?
可以打開微信, 然后發一個消息或者是讀取一張照片,而后你再次打開著張照片的時候就直接從內存里面讀取;
之后你再關閉網絡, 然后你在重新進入app你會發現一樣是可以獲取到之前緩存的信息的;
那大概就是他們緩存進的不僅僅是內存還緩存到sd里面, 當沒有網絡的時候直接從sd里面讀取緩存;
LruCache DisLruCache;
我們先看如下一段代碼 初始化ImageLoader
ImageLoader imageLoader = new ImageLoader(MyQueue.getInstance(context), new ImageLoader.ImageCache() {
// 根據url獲取Bitmap
@Override
public Bitmap getBitmap(String url) {
return null;
}
//url作為表示保存Bitmap
@Override
public void putBitmap(String url, Bitmap bitmap) {
}
})</code></pre>
當實例化ImageCache 重寫兩個方法; 根據名稱就能知道兩個方法的作用;
先放上兩段代碼
private Context mContext;
private LruCache<String,Bitmap> lruCache;
public MyLruCache(Context context) {
this.mContext = context;
//最大緩存容量
int maxSize = 10 * 1024 * 1024;
lruCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getHeight() * value.getRowBytes();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return lruCache.get(url);
}
@Override
public void putBitmap(String s, Bitmap bitmap) {
lruCache.put(s,bitmap);
}
以上就是是一個典型的內存緩存;
public class MySystemDiskLru {
public DiskLruCache mDiskLruCache = null;
private static MySystemDiskLru mySystemDiskLru;
public Context context;
private MySystemDiskLru(Context context) {
this.context = context;
try {
mDiskLruCache = DiskLruCache.open(getDirectory("VolleyImageCache"),
AppUtils.getVersionCode(context), 1, 10 * 1024 * 1024);
} catch (IOException e) {
e.printStackTrace();
}
}
// 單列
public static MySystemDiskLru getInstance(Context context) {
if (mySystemDiskLru == null) {
mySystemDiskLru = new MySystemDiskLru(context);
}
return mySystemDiskLru;
}
/**
* 獲取緩存地址
*/
public File getDirectory(String PathName) {
String path = null;
if (SDCardUtils.isSDCardEnable()) {
path = SDCardUtils.getSDCardPath() + PathName;
} else {
path = SDCardUtils.getRootDirectoryPath() + PathName;
}
File file = new File(path);
if (file.exists()) {
file.mkdirs();
}
Log.i("TAG","------path-" + path);
return file;
}
/**
* 保存
**/
public void save(String url, Bitmap bitmap) {
BufferedOutputStream os = null;
OutputStream outputStream = null;
DiskLruCache.Editor editor = null;
String key = hashKeyForDisk(url);
try {
editor = mDiskLruCache.edit(key);
if (editor != null) {
os = new BufferedOutputStream(editor.newOutputStream(0));
// 利用Bitmap工具類,將Bitmap轉換成輸入流
os.write(BitmapUtils.compressBitmap(bitmap));
}
/** 切記刷新 */
os.flush();
editor.commit();
mDiskLruCache.flush();
} catch (IOException e) {
e.printStackTrace();
// 如果沒成功數據回滾
try {
editor.abort();
} catch (IOException e1) {
e1.printStackTrace();
}
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 獲取
**/
public Bitmap getBitmap(String url) {
Bitmap bitmap = null;
InputStream is = null;
DiskLruCache.Snapshot snapshot = null;
String key = hashKeyForDisk(url);
try {
snapshot = mDiskLruCache.get(key);
// 利用了工廠將io流轉換成bitmap
if (snapshot != null) {
is = snapshot.getInputStream(0);
// Options op = new Options();
// op.inSampleSize = 4; ,new Rect(),op
// try {
bitmap = BitmapFactory.decodeStream(is);
// } catch (OutOfMemoryError err) {
// Log.e("", "====oom-----------");
// }
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return bitmap;
}
/**
* 將Url文件轉換成MD5唯一標示
*/
public String hashKeyForDisk(String key) {
String cacheKey;
try {
final MessageDigest mDigest = MessageDigest.getInstance("MD5");
mDigest.update(key.getBytes());
cacheKey = bytesToHexString(mDigest.digest());
} catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode());
}
return cacheKey;
}
private String bytesToHexString(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();
}
}
以上代碼則是硬盤緩存,要注意的地方都已經寫上注釋了;
那么這個緩存是在什么時候調用呢?
這里呢其實不需要我們擔心,因為ImageLoad 已經在內部幫我們做好了
看以下我自己運行的demo;
這是第一次使用加載圖片

可以清楚的看到加載中的圖片

這是讀取緩存好的并沒有出現加載中的照片,非常流暢;
來自:http://www.jianshu.com/p/e3ce0161cfa9
本文由用戶 ngl1125 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!