android异步图片加载之handler+线程池+消息队列模式+缓存
来源:互联网 发布:php一句话木马 密码 编辑:程序博客网 时间:2024/06/14 14:33
http://blog.csdn.net/soesa/article/details/7787922
假象现在有这样一个需求:
一个微博客户端或者多媒体客户端需要从服务端拉取一些数据,该数据中包含了很多图片,如果不用异步加载方式,可能会使主线程阻塞导致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+线程池+消息队列模式+缓存
- Android实现ListView异步加载图片+缓存+线程池管理
- android 之图片异步加载,带缓存。
- handler加线程模式实现android应用的异步加载
- Android异步消息处理线程之----Looper+MessageQueue+Handler
- Android之多线程----异步消息处理机制之Handler详解
- Android Handler ExecutorService(线程池) 缓存模式
- Android listview异步加载图片(线程池,内存缓存,SD卡缓存)优化显示
- Android线程池异步加载图片,可LIFO,可FIFO加载,四级缓存
- android 图片异步加载(线程池,等待,唤醒;图片缓存在内存)
- 使用Android新式LruCache缓存图片,基于线程池异步加载图片
- Android Handler(子线程Handler)异步消息处理机制的妙用(活用信号量) 创建强大的图片加载类
- Android 异步加载图片+线程池+缓存(详细介绍,深入了解)
- android中图片异步加载工具类 ---利用双缓存技术和线程池
- android之图片异步加载并缓存到本地
- 关于 I/O 的五分钟法则
- 一个程序员近20年工资单
- Linux常用命令记录及解释
- cf之app解读
- 配置Tomcat支持UTF-8编码
- android异步图片加载之handler+线程池+消息队列模式+缓存
- JavaScript Date 对象参考手册
- IOCP教程
- AOP反模式
- 【Android开发学习29】界面控件之列表控件(ListView)--显示图片和文本
- 使用PowerDesigner花ER图详细教程(1 )
- 转 IOCP+WinSock2新函数打造高性能SOCKET池
- 数字签名和数字信封的区别
- 基于.net开发chrome核心浏览器【一】