您的位置:首页 > Web前端

SoftReference缓存图片以及图片的异步加载

2013-10-08 09:50 429 查看



Java中的SoftReference即对象的软引用。如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。使用软引用能防止内存泄露,增强程序的健壮性。

SoftReference的特点是它的一个实例保存对一个Java对象的软引用,该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。另外,一旦垃圾线程回收该Java对象之后,get()方法将返回null

用Map集合缓存软引用的Bitmap对象

Map<String, SoftReference<Bitmap>> imageCache = new new HashMap<String, SoftReference<Bitmap>>();

//强引用的Bitmap对象

Bitmap bitmap = BitmapFactory.decodeStream(InputStream);

//软引用的Bitmap对象

SoftReference<Bitmap> bitmapcache = new SoftReference<Bitmap>(bitmap);

//添加该对象到Map中使其缓存

imageCache.put("1",softRbitmap);

..

.

//从缓存中取软引用的Bitmap对象

SoftReference<Bitmap> bitmapcache_ = imageCache.get("1");

//取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得空

Bitmap bitmap_ = bitmapcache_.get();

如果程序中需要从网上加载大量的图片 这时就考虑采用在sdcard上建立临时文件夹缓存这些图片了。

/**
*
*图片异步加载类
*/
public class AsyncImageLoader {
private HashMap<String, SoftReference<Bitmap>> imageCache;
private ExecutorService executorService = Executors.newFixedThreadPool(5); // 固定五个线程来执行任�?
private static String TAG = "AsyncImageLoader";

public AsyncImageLoader() {
imageCache = new HashMap<String, SoftReference<Bitmap>>();
}

/**
* 1、首先查看缓存中是否存在,存在则加载 2、不存在则再去sd卡上找,有则放到缓存中, 3、没有则去服务器上下载,并保存到SD卡上
*
* @param imageUrl
* @param imageCallback
* @return Bitmap类型的图片
*/
public Bitmap loadDrawable(final String patch, final String imageUrl,final Context _context,
final ImageCallback imageCallback) {

if (imageCache.containsKey(imageUrl))
{
SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
Bitmap drawable = softReference.get();
if (drawable != null)
{
Log.d(TAG, "缓存读取图片 : " + imageUrl);
return drawable;
}
}

// 缓存中没有图像,则从文件夹取出数据,并将取出的数据缓存到内存
String fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1).trim();
Bitmap have = null;
try {
have = SDCardFile.readImageSdcardFile(fileName, patch);
}catch (IOException e) {
Log.d(TAG, "there is a erroe at load image :IOException");
}
catch (Exception e) {
Log.d(TAG, "there is a erroe at load image :Exception");
}

if (have != null) {
Log.d(TAG, "本地读取图片 : " + imageUrl);
imageCache.put(imageUrl, new SoftReference<Bitmap>(have));
return have;
}

// 缓存及本地文件夹均没有图片,则访问网络获得图片,并缓存到本地内存及SD卡中
executorService.submit(new Runnable() {
public void run() {
try {
Log.d(TAG, "网络获取图片 : " + imageUrl);
Bitmap drawable = loadImageFromUrl(imageUrl, patch,_context);
imageCache.put(imageUrl,
new SoftReference<Bitmap>(drawable));
imageCallback.imageLoaded(drawable, imageUrl);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});

return null;
}

// 请求服务器图片
public static Bitmap loadImageFromUrl(String url, String path,Context context) {
String fileName = url.substring(url.lastIndexOf("/") + 1).trim();
String otherString = url.substring(0, url.lastIndexOf("/") + 1);
String mURL = otherString + URLEncoder.encode(fileName);

Bitmap bm = null;
InputStream is = null;
BufferedInputStream bis = null;
if (url != null && !(url.equals(""))) {

try {
URL aURL = new URL(mURL);
HttpURLConnection conn = (HttpURLConnection) aURL
.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.connect();
if (((HttpURLConnection) conn).getResponseCode() == HttpURLConnection.HTTP_OK) {
is = conn.getInputStream();
bis = new BufferedInputStream(is, 8192);

// //////////////////////////////计算压缩倍数///////////////////////////////////////
BitmapFactory.Options options = new BitmapFactory.Options();
bm = BitmapFactory.decodeStream(is, null, options);
options.inJustDecodeBounds = false; // 仅获取宽高信息,不加载整个图片
int old_height = options.outHeight;
int old_width = options.outWidth;
int max_height = ConfigValue.BOOKCENTREIMAGEHEIGHT;
int max_width = ConfigValue.BOOKCENTREIMAGEWIDTH;
if(old_height>max_height){
bm = SDCardFile.compressIamge(max_height, max_width, bm);
}
SDCardFile.saveImageSdcardFile(bm, fileName, path);
}

if (bis != null) {
bis.close();
}
if (is != null) {
is.close();
}

}  catch (SocketTimeoutException e) {
Log.d(TAG, "进入了SocketTimeoutException");
Tools.saveError(context, mURL, "", "AsyncImageLoader SocketTimeoutException");
e.printStackTrace();
} catch (ConnectTimeoutException e) {
Log.d(TAG, "进入了ConnectTimeoutException");
Tools.saveError(context, mURL, "", "AsyncImageLoader ConnectTimeoutException");
e.printStackTrace();
} catch (UnknownHostException e) {
Log.d(TAG, "进入了UnknownHostException");
Tools.saveError(context, mURL, "", "AsyncImageLoader UnknownHostException");
e.printStackTrace();
}
catch (SocketException e) {
Log.d(TAG, "进入了SocketException");
Tools.saveError(context, mURL, "", "AsyncImageLoader SocketException");
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
Tools.saveError(context, mURL, "", "AsyncImageLoader Exception");
Log.d(TAG, "there is a excepion when load image");
}

}

return bm;
}

public interface ImageCallback {
public void imageLoaded(Bitmap imageDrawable, String imageUrl);
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐