Android 圖片三級緩存機制工具類封裝

Android 圖片三級緩存機制工具類封裝

三級緩存分別是:html

  1. 軟引用SoftReference,cache在內存中web

  2. 文件緩存在本地SDcard文件夾中,遇到文件名相同的圖片則從本地取,且加入軟引用中緩存

  3. 從網絡下載,並保存在本地,且加入軟引用中網絡

其中緩存的文件,其文件名通過MD5轉換,去掉了文件路徑中的斜槓,目前該方法全存儲成png格式的,也可進一步優化。注意須要靜態初始化軟引用,可保證全局有效。異步

實現的方法是經過集成一個AsyncTask,並定製裏面的內容。好像也沒什麼特別好說的...ide

在作listview列表的時候,可把這一個task加入viewholder裏,這樣就能保證每一個控件的惟一性了,比起封裝一個AsyncImageView,要更簡潔一些,而且能知足使用的要求工具

代碼以下:優化

/**
 * 異步根據URL獲取圖片
 * 修改加入本地緩存和軟引用
 * @author Jackland_zgl
*
*/
@SuppressLint("NewApi")
public class LoadingImgTask extends AsyncTask<Void, Void, Bitmap> {

 public static final String URL_KEY ="url";
 public static final String BITMAP_KEY ="bitmap";

 public static final String ImageCacheFilePath ="/sdcard/xiaomai/ImageCache/";
 private String url;
 private static HashMap<String, SoftReference<Bitmap>> cache; 
 RefreshDelegate refreshDelegate;

 /** 靜態初始化軟引用 */
 static { 
 cache = new HashMap<String, SoftReference<Bitmap>>(); 
}


 public LoadingImgTask(String url,RefreshDelegate rd) {
 this.url = url;
 this.refreshDelegate = rd;
}

@Override
 protected Bitmap doInBackground(Void... params) {

 Bitmap bm;
//1從軟引用中取
 bm = getBitmapFromCache(url);
 if (bm!=null) {
// Log.d("image","緩存");
 return bm;
}

//2從本地中取
 bm = getBitmapFromLocal(ImageCacheFilePath , modifyUriToFileName(url));
 if (bm!=null) {
//放入緩存
 cache.put(url, new SoftReference<Bitmap>(bm));
// Log.d("image","本地");
 return bm;
}

 //3從網絡取 ,若能取出則緩存
 bm = loadImageFromNet(url);
 if (bm!=null){
 try {
saveImageToSD(ImageCacheFilePath+modifyUriToFileName(url),bm);
 } catch (IOException e) {
 // TODO Auto-generated catch block
e.printStackTrace();
}
 cache.put(url, new SoftReference<Bitmap>(bm));
// Log.d("image","網絡");
}
 return bm;
}

@Override
 protected void onPostExecute(Bitmap result) {
 HashMap<String,Object> map = new HashMap<String,Object>();
 map.put(RefreshDelegate.KEY_URL, url);
 map.put(RefreshDelegate.KEY_BITMAP, result);
 if (refreshDelegate!=null)
refreshDelegate.refresh(map);
}

/**
 * 從緩存中獲取圖片
 * @param url
*/
 public Bitmap getBitmapFromCache(String url) { 
 Bitmap bitmap = null;
 if (cache.containsKey(url)) { 
 bitmap = cache.get(url).get(); 
}
 return bitmap; 
}

/**
 * 從本地獲取
 * @param path
 * @param url
 * @return
*/
 public Bitmap getBitmapFromLocal(String path,String url){
 return BitmapFactory.decodeFile(path+url);

}

/**
 * 從網絡讀取
 * @param url
 * @return
*/
 public static Bitmap loadImageFromNet(String url) {
 URL m;
 InputStream i = null;
 if (url == null) {
 return null;
}
 try {
 m = new URL(url);

 i = (InputStream) m.getContent();
 } catch (MalformedURLException e1) {
e1.printStackTrace();
 } catch (IOException e) {
e.printStackTrace();
 } catch (Exception e2) {
e2.printStackTrace();
}
 if (i == null) {
 return null;
}
 return BitmapFactory.decodeStream(i);
}

/**
 * 寫圖片文件到SD卡
*
 * @throws IOException
*/
 public static void saveImageToSD(String filePath,
 Bitmap bitmap) throws IOException {
Log.d("image","存在本地:"+filePath);
 if (bitmap != null) {
 File file = new File(filePath.substring(0,
filePath.lastIndexOf(File.separator)));
 if (!file.exists()) {
file.mkdirs();
}
 FileOutputStream fos = new FileOutputStream(filePath);
 ByteArrayOutputStream stream = new ByteArrayOutputStream();
 bitmap.compress(CompressFormat.PNG, 100, stream);

fos.write(stream.toByteArray());
fos.close();
}
}

/**
 * 修改URL裏的斜槓
 * @param Url
 * @return
*/
 public static String modifyUriToFileName(String Url){
// String mUrl = Url.replaceAll("/","_").replaceAll("\.","-").replaceAll(":","_")+".jpg";
 String mUrl = MD5Util.md5(Url)+".png";
 return mUrl;
}


/**
 * 刷新代理
 * @author Jackland_zgl
*
*/
 public interface RefreshDelegate{
 public static String KEY_URL="url";
 public static String KEY_BITMAP="bitmap";

 public int refresh(HashMap<String,Object> result);

}
}

關於異步加載圖片,下面的幾篇博客可供參考: http://www.iteye.com/topic/1118828http://blog.csdn.net/geniusxiaoyu/article/details/7470163http://blog.csdn.net/zshshuai/article/details/7798086 http://www.2cto.com/kf/201403/283382.htmlthis

以上幾篇代碼沒有提到LRU的實現,使用LRU能夠真正的吸收內存空間作緩存,可是目前我實現的代碼不怎麼有效,在此處mark一下,調成功以後再更新這個封裝類url

相關文章
相關標籤/搜索