Android异步加载图片(一)下载完图片之后,如何更新界面
2015-03-02 20:08
274 查看
场景
想象一下加载图片的时候,ImageView首先设置一个placeHolder,然后开启AsyncTask去加载合适的图片,图片加载成功之后, 怎么去更新ImageView?一般来讲,有两种处理方式,第一种:将ImageView传递给AsyncTask,task执行完之后,直接ImageView设置bitmap,第二种:Task执行完毕之后,将Bitmap存储在缓存里,通知主线程的view,进行数据更新。将ImageView传递给AsyncTask
要求
ListView或者GridView会复用ImageView,例如pos为4的ImageView4开启了一个AsyncTask,用户滚动到了pos为8的位置,复用了ImageView4,即使这个时候AsyncTask更新完了,但是也不能去更新ImageView4。AsyncTask不能阻止ImageView的内存释放,例如当用户离开这个页面的时候,应该销毁界面,AsyncTask应当避免造成内存泄露
AsyncTask执行完毕之后,应该能够拿到ImageView,并且ImageView设置Bitmap之前需要判断ImageView与Drawable和Task之间必须一一对应
实现
BitmapWorkerTask继承AsyncTask,弱引用ImageView,这样AsyncTask既可以在执行完毕之后取到ImageView更新Bitmap,又不会阻止ImageView被释放ImageView每次都会设置一个placeHolder AsyncDrawable,在AsyncDrawable中弱引用AsyncTask,当AsyncTask执行完毕,可以通过ImageView get AsyncDrawable,然后通过AsyncDrawable获取到BitmapTask,判断task是否是同一个task,如果是,那么就能确定ImageView,AsyncDrawable,AsyncTask一一对应,可以进行数据更新,此外AsyncTask完全执行完毕之后,也可以直接被释放掉了,AsyncDrawable不会阻碍AsyncTask被释放
Task执行完毕之后,将Bitmap存储在缓存里,通知主线程的view,进行数据更新
缺点:
盲目刷新,效率太低,特别是ImageView特别多,AsyncTask执行很快,那么刷新的频率会特别高,这样会导致页面不断刷新,甚至卡顿总结
ImageView,BitmapWorkerTask,AsyncDrawable的关系
BitmapWorkerTask持有一个WeakReference imageViewReference,弱引用ImageView,用作异步处理加载图片的任务。AsyncDrawable巧妙的引用持有弱引用WeakReference bitmapWorkerTaskReference,AsyncDrawable继承自BitmapDrawable,这样ImageView就可以setImageBitmap(AsyncDrawable)
AsyncDrawable中弱引用BitmapWorkerTask,ImageView.getDrawable又可以获得AsyncDrawable,继而获得BitmapWorkerTask
关键代码
protected static class AsyncDrawable extends BitmapDrawable { private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { super(res, bitmap); bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(bitmapWorkerTask); } public BitmapWorkerTask getBitmapWorkerTask() { return bitmapWorkerTaskReference.get(); } }
protected class BitmapWorkerTask extends AsyncTask<Object, Void, BitmapDrawable> { private Object data; private final WeakReference<ImageView> imageViewReference; public BitmapWorkerTask(ImageView imageView) { imageViewReference = new WeakReference<ImageView>(imageView); }
final AsyncDrawable asyncDrawable = new AsyncDrawable(mResources, map, task); imageView.setImageDrawable(asyncDrawable);
protected void onPostExecute(BitmapDrawable value) { final ImageView imageView = getAttachedImageView(); if (value != null && imageView != null) { imageView.setImageDrawable(value); afterGetBitmap(imageView, value); } }
相关文章推荐
- Android下载图片 图片的异步加载 和缓存存取
- 由于Android列表视图复用到之后的Imageview异步加载图片时候闪烁问题
- Android:ListView异步加载图片(实现网络下载、存储本地、缓存内存、压缩显示)
- Android 异步加载数据 AsyncTask异步更新界面
- ListView优化使用imageLoader下载和缓存图片,图片异步加载,解决图片多了之后容易卡顿。
- 实例讲解Android中如何实现图片的异步加载功能
- 实例讲解Android中如何实现图片的异步加载功能
- Android实现Listview异步加载网络图片并动态更新的方法
- 【移动开发】Android中异步加载数据(二)AsyncTask异步更新界面
- 实例讲解Android中如何实现图片的异步加载功能
- 实例讲解Android中如何实现图片的异步加载功能
- Android 如何实现ListView异步加载网络图片
- android listview利用多线程异步加载图片并更新视图
- Android中异步加载数据(二)AsyncTask异步更新界面
- Android:仿微博Listview与多线程功能(JSON、数据下载、图片加载、Listview、异步任务)
- Android 利用多线程异步加载图,并把图片处理成圆角,并更新视图
- Android 异步加载图片,使用LruCache和SD卡或手机缓存(使用线程池下载图片)
- Android:仿微博Listview与多线程功能(JSON、数据下载、图片加载、Listview、异步任务)
- android 加载图片本地有缓存,如何实时更新服务器上修改的图片
- 实例讲解Android中如何实现图片的异步加载功能