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

来源:互联网 发布:java中级程序员面试题 编辑:程序博客网 时间:2024/05/22 06:16

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);}}