1、緩存類型
(1)強引用
程式崩潰也不會回收對象
例:平時我們new出來的指向的引用就是強引用
(2)弱引用
垃圾回收一跑,就很容易被回收
應用:有些需要需要畫面一移出螢幕,就要回收該資源,這時我們可以用弱引用處理
XUtils中BitmapUtils的緩存機制
(3)軟引用
1、垃圾回收線程運作時,不會回收該引用
2、隻有在程式記憶體溢出抛出OOM異常之前執行回收操作
應用:三級緩存
(4)虛引用
該引用很少用到
2、自定義三級緩存
/**
* 圖檔的三級緩存類
*
*
* 1. 記憶體擷取資料 2. 本地磁盤擷取資料 cache 3. 網絡擷取資料
*
* @author Administrator
*
*/
public class BitmapCacheUtils {
private HomeActivity mContext;
private int maxSize = (int) (Runtime.getRuntime().freeMemory() / 2);// 擷取可用記憶體的一半做為緩存容器大小
private Map<ImageView,String> iv_urls = new HashMap<ImageView,String>();//記錄最後顯示想iv對應url
private LruCache<String, Bitmap> mLruCaches = new LruCache<String, Bitmap>(
maxSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
// TODO Auto-generated method stub
return value.getRowBytes() * value.getHeight();// return
// value.getByteCount();//擷取位元組的大小
}
};
private ExecutorService mThreadPool;//線程池
public BitmapCacheUtils(HomeActivity context) {
mContext = context;
mThreadPool = Executors.newFixedThreadPool(6);
}
public void display(ImageView iv_temp, String url) {
// 1. 記憶體擷取資料
Bitmap bitmap = mLruCaches.get(url);
if (bitmap != null) {
PrintLog.print("從記憶體中擷取圖檔");
// 緩存中有資料
iv_temp.setImageBitmap(bitmap);
return;
}
// 2. 本地磁盤擷取資料
bitmap = getBitmapFromLocal(url);
if (bitmap != null) {
PrintLog.print("從本地擷取圖檔");
// 本地有圖檔
iv_temp.setImageBitmap(bitmap);
//往記憶體中儲存一份
writeBitmap2Memery(url, bitmap);
return;
}
// 3. 網絡擷取資料
iv_urls.put(iv_temp, url);
getBitmapFromNet(iv_temp, url);
}
private void getBitmapFromNet(ImageView iv_temp, String url) {
// 線程 線程池
//new Thread(new BitmapFromNet(iv_temp, url)).start();
mThreadPool.submit(new BitmapFromNet(iv_temp, url));
}
/**
* 網絡請求資料
*
* @author Administrator
*
*/
private class BitmapFromNet implements Runnable {
private ImageView iv_bitmap;
private String mUrl;
public BitmapFromNet(ImageView iv_temp, String url) {
// TODO Auto-generated constructor stub
this.iv_bitmap = iv_temp;
this.mUrl = url;
}
@Override
public void run() {
// 1. 請求網絡
try {
URL url = new URL(mUrl);
HttpURLConnection con = (HttpURLConnection) url
.openConnection();
con.setConnectTimeout(7000);// 7秒逾時設定
con.setRequestMethod("GET");// 請求方式
int code = con.getResponseCode();
if (code == 200) {
// success
InputStream is = con.getInputStream();
// 把is 轉成 bitmap
final Bitmap bitmap = BitmapFactory.decodeStream(is);
// 1. 記憶體存放一份
writeBitmap2Memery(mUrl, bitmap);
// 2. 本地Cache目錄存放一份
writeBitmap2Local(mUrl, bitmap);
// 3. 顯示圖檔
mContext.runOnUiThread(new Runnable() {
@Override
public void run() {
//判斷目前url或者的圖檔是否是最新的
if (iv_urls.get(iv_bitmap).equals(mUrl)) {
//最新的url
// 運作在主線程中
iv_bitmap.setImageBitmap(bitmap);
PrintLog.print("從網絡擷取圖檔。。。。。。。");
} else {
//網速慢造成的圖檔錯位 不顯示圖檔
}
}
});
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 往記憶體中儲存
*
* @param url
* @param bitmap
*/
public void writeBitmap2Memery(String url, Bitmap bitmap) {
// TODO Auto-generated method stub
mLruCaches.put(url, bitmap);// 記憶體中儲存一份
}
/**
* 從本地擷取圖檔
*
* @param url
* @return
*/
public Bitmap getBitmapFromLocal(String mUrl) {
File file = new File(mContext.getCacheDir(), mUrl.substring(mUrl
.lastIndexOf('/') + 1));
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
return bitmap;
}
/**
* 往本地中儲存
*
* @param mUrl
* @param bitmap
*/
public void writeBitmap2Local(String mUrl, Bitmap bitmap) {
// cache
File cacheDir = mContext.getCacheDir();
File file = new File(cacheDir,
mUrl.substring(mUrl.lastIndexOf('/') + 1));
try {
bitmap.compress(CompressFormat.JPEG, 100,
new FileOutputStream(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}