android中用弱引用管理bitmap

来源:互联网 发布:海康摄像头无网络视频 编辑:程序博客网 时间:2024/06/10 19:36
软引用,需要通过SoftReference类来实现,当一个对象只有一个软引用,它有可能被垃圾回收机制回收。内存空间足够时,不会被回收,不足够时将被回收 

弱引用,需要通过WeakReference类来实现,当垃圾回收机制运行时,不管内存是否足够,总会回收该对象所占用的内存


众所周知,使用bitmap时容易引起oom,虽然我们可以在bitmap不适用的时候通过recycle方法释放bitmap占用的内存,但是如果这个方法调用的时间点不合理,很容易引起 use a recycle bitmap的异常。

对此,可以使用弱引用来管理bitmap。将所有用到的bitmap对象放到一个hashmap中,用弱引用来保存,如果再用到这个bitmap的时候,根据相应的key直接取出来,相当于一个高速缓存池。如果确定不再使用的时候手动将其recycle,保证这个程序不会重复创建过多的bitmap对象。此外弱引用对象可以在系统内存不足的时候自动被系统回收。


以下是小弟写的一个弱引用管理bitmap的工具类代码,仅供学习参考


public class ImageUtils {/**保存图片的集合,key为图片的url*/public static Map<String,WeakReference<Drawable>> imageCache = new HashMap<String, WeakReference<Drawable>>();private static MyHandler myHandler = new MyHandler(Looper.getMainLooper());public static void sendMessage(IFBackListener backlistener,Object exInfo){Message m = Message.obtain();m.what = 0;m.obj = new Object[]{backlistener,exInfo};myHandler.sendMessage(m);}private static class MyHandler extends Handler{MyHandler(Looper looper){super(looper);}public void handleMessage(Message m) {//处理消息Object[] pars = (Object[])m.obj;if(pars[0] instanceof IFBackListener){((IFBackListener)pars[0]).processBack(pars[1]);}}}/** * 根据url获取图片,如果缓存中没有这个图片,会返回宽高并异步加载图片 * Description: * @param callBack回调 * @param url图片url * @param needAsync是否需要异步加载 * @return *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-24 下午12:09:21 */public static Object newImage(IFBackListener callBack, String url, boolean needAsync) {if(url == null || url.equals("")) {return null;}if(needAsync) {//需要异步加载return newImageByAsync(callBack, url);} else {//不需要异步加载Drawable drawable = (Drawable) getImageFromCache(url);if(drawable != null) {//缓存中有这个图片return drawable;} else {drawable = newDrawable(url);return drawable;} }}/** * 根据url获取一个Drawable * Description: * @param url * @return *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-31 上午10:43:58 */public static Drawable newDrawable(String url) {if(url == null || url.equals("")) {return null;}Drawable drawable = null;drawable = new BitmapDrawable(url);if(drawable != null) {//将图片加入缓存ImageUtils.imageCache.put(url, new WeakReference<Drawable>(drawable));}return drawable;}/** * 根据url获取图片,如果缓存中没有这个图片,会返回宽高并异步加载图片 * Description: * @param callBack回调 * @param url图片url * @return *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-24 下午12:09:21 */public static Object newImageByAsync(IFBackListener callBack, String url) {if(url == null || url.equals("")) {return null;}Drawable d = (Drawable) getImageFromCache(url);if(d != null) {//缓存中有这个图片return d;} else {//缓存中没有这个图片,那么获取图片的宽高int[] options = null;options = getImageBounds(url);if(options != null && options[0] > 0 && options[1] >0) {//存在正常的宽高if(callBack != null) {//回调callBack.processBack(options);}//发送消息,异步加载图片sendMessage(callBack, url);return null;}} return null;}/** * 到集合缓存中查找图片,有则返回Drawable对象,没有返回空 * Description: * @param url * @return *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-24 上午10:34:33 */public static Object getImageFromCache(String url) {if(url == null || url.equals("")) {return null;}if(hasImage(url)) {//缓存中有这个图片Drawable d = getDrawableFromCache(url);if(d != null) {return d;}}return null;}/** * 图片是否存在 * Description: * @param url * @return *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-24 上午10:07:15 */public static boolean hasImage(String url) {return imageCache.containsKey(url);}/** * 获取指定url的图片的宽高 * Description: * @param url * @return *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-23 下午05:24:34 */private static int[] getImageBounds(String url) {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true; //只获取宽高    BitmapFactory.decodeFile(url, options);//这里返回的bitmap应为null    return new int[]{options.outWidth,options.outHeight};}/** * 根据key到缓存集合中获取Drawable * Description: * @param key * @return *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-23 下午05:23:59 */private static Drawable getDrawableFromCache(String key) {if(hasImage(key)) {//缓存中有这个图片WeakReference<Drawable> ref = imageCache.get(key);Drawable d = ref.get();if (d != null) {return d;}}return null;}/** * 回收指定图片 * Description: * @param url图片的url,根据这个url到集合缓存中找图片 *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-23 下午05:51:45 */public static void recycleImage(String url) {if(url == null || url.equals("")) {return;}Drawable d = getDrawableFromCache(url);if(d != null) {Bitmap b = ((BitmapDrawable)d).getBitmap();if(b != null && !b.isRecycled()){    b.recycle();}b = null;d = null;}}/** * 清空集合中所有缓存 * Description: *<br/> ModifiedLog: *<br/> Log ID: 1.0 (Log编号 依次递增) * <br/>Modified By: liubin Email:liubin@d-heaven.com at 2012-8-23 下午05:36:07 */public static void clearImageCache() {if(imageCache == null ||imageCache.isEmpty()) {return;}//遍历集合,找出所有Drawable,将其中bitmap回收并置空for(Map.Entry<String,WeakReference<Drawable>> entry:imageCache.entrySet()){Drawable d = entry.getValue().get();if(d != null) {Bitmap b = ((BitmapDrawable)d).getBitmap();if(b != null && !b.isRecycled()){    b.recycle();}b = null;d = null;}}imageCache.clear();}}interface IFBackListener {Object processBack(Object targetO);}