android异步图片加载三之handler+线程池+消息队列模式+缓存
2013-06-04 13:46
651 查看
假象现在有这样一个需求:
一个微博客户端或者多媒体客户端需要从服务端拉取一些数据,该数据中包含了很多图片,如果不用异步加载方式,可能会使主线程阻塞导致ANR异常,但是异步加载后如果每次都通过网络去下载图片,性能上会差很多,而且也会浪费流量,导致用户的不满,故现在增加一个缓存用来存储图片,缓存中包含内存存储和sdcard存储。先从缓存中去,在缓存中先从内存中取出,如果内存中没有再从sdcard去,如果sdcard中存在则直接返回该图片资源并放入内存中,如果两者都没有则从网络上下载,下载后并放入sdcard中供下次使用,这样就节约了资源开销,下面是主要代码:
PicManager(用来处理图片的操作):
ImgLoader(用来加载图片):
ImgCallback callback是一个接口,用来刷新界面:
一个微博客户端或者多媒体客户端需要从服务端拉取一些数据,该数据中包含了很多图片,如果不用异步加载方式,可能会使主线程阻塞导致ANR异常,但是异步加载后如果每次都通过网络去下载图片,性能上会差很多,而且也会浪费流量,导致用户的不满,故现在增加一个缓存用来存储图片,缓存中包含内存存储和sdcard存储。先从缓存中去,在缓存中先从内存中取出,如果内存中没有再从sdcard去,如果sdcard中存在则直接返回该图片资源并放入内存中,如果两者都没有则从网络上下载,下载后并放入sdcard中供下次使用,这样就节约了资源开销,下面是主要代码:
PicManager(用来处理图片的操作):
public class PicManager { private Map<String,SoftReference<Bitmap>> imgCache ; private Context ctx; public PicManager(Map<String,SoftReference<Bitmap>> imgCache,Context ctx) { this.ctx = ctx; this.imgCache = imgCache; } /** * 从网络上下载 * @param url * @return */ public Bitmap getBitMapFromUrl(String url) { Bitmap bitmap = null; URL u =null; HttpURLConnection conn = null; InputStream is = null; try { u = new URL(url); conn = (HttpURLConnection)u.openConnection(); is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); } catch (Exception e) { e.printStackTrace(); } return bitmap; } /** * 从文件中读取 * @return * @throws Exception */ private Bitmap getBitMapFromSDCard(String url) throws Exception { Bitmap bitmap = null; String filename = MD5Util.getMD5(url); FileInputStream fis = ctx.openFileInput(filename); bitmap = BitmapFactory.decodeStream(fis); return bitmap; } /** * 从缓存中读取 * @param url * @return * @throws Exception */ public Bitmap getImgFromCache(String url) throws Exception { Bitmap bitmap = null; //从内存中读取 if(imgCache.containsKey(url)) { synchronized (imgCache) { SoftReference<Bitmap> bitmapReference = imgCache.get(url); if(null != bitmapReference) { bitmap = bitmapReference.get(); } } } else {//否则从文件中读取 bitmap = getBitMapFromSDCard(url); //将图片保存进内存中 imgCache.put(url, new SoftReference<Bitmap>(bitmap)); } return bitmap; } /** * 将图片写入sdcard中 * @param bitmap * @param url * @throws Exception */ public void writePic2SDCard(Bitmap bitmap,String url) throws Exception { String filename = MD5Util.getMD5(url); FileOutputStream fos = ctx.openFileOutput(filename, ctx.MODE_APPEND); byte[] bitmapByte = PictureUtil.bitmap2Byte(bitmap); ByteArrayInputStream bis = new ByteArrayInputStream(bitmapByte); int len = 0; byte[] b = new byte[bis.available()]; while((len = bis.read(b)) != -1) { fos.write(b, 0, len); } if(null != bis) { bis.close(); } if(null != fos) { fos.close(); } } }
ImgLoader(用来加载图片):
public class ImgLoader { private Map<String,SoftReference<Bitmap>> imgCache = new HashMap<String,SoftReference<Bitmap>>(); private Context ctx; public ImgLoader(Context ctx) { this.ctx = ctx; } private PicManager manager = new PicManager(imgCache,ctx); private Handler handler = new Handler(); private ExecutorService threadPool = Executors.newFixedThreadPool(5); public Bitmap loadImg(final String url,final ImgCallback callback) { //先从缓存中读取图片资源 Bitmap bitmap = null; try { bitmap = manager.getImgFromCache(url);; if(null == bitmap) { //开启线程从网络上下载 threadPool.submit(new Runnable() {//submit方法确保下载是从线程池中的线程执行 @Override public void run() { final Bitmap bitmapFromUrl = manager.getBitMapFromUrl(url); try { manager.writePic2SDCard(bitmapFromUrl,url); } catch (Exception e) { e.printStackTrace(); } handler.post(new Runnable() { @Override public void run() { callback.refresh(bitmapFromUrl); } }); } }); } else { } } catch (Exception e) { e.printStackTrace(); } return bitmap; } }
ImgCallback callback是一个接口,用来刷新界面:
public interface ImgCallback { public void refresh(Bitmap bitmap); }
相关文章推荐
- android 异步图片加载四之handler+线程池+消息队列模式+缓存
- android异步图片加载三之handler+线程池+消息队列模式+缓存
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android消息处理机制:源码剖析Handler、Looper,并实现图片异步加载
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android图片异步加载一之传统的handler+runnable模式
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android 异步加载图片,使用LruCache和SD卡或手机缓存(使用线程池下载图片)
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android listview异步加载图片(线程池,内存缓存,SD卡缓存)优化显示
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- (4.1.21.4)Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- ANDROID_MARS学习笔记_S04_009_用java.lang.ref.SoftReference作缓存,android.os.Handler和new Thread异步加载略图片
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类