zoukankan      html  css  js  c++  java
  • Android异步加载图片(一)下载完图片之后,如何更新界面

    场景

    想象一下加载图片的时候,ImageView首先设置一个placeHolder,然后开启AsyncTask去加载合适的图片,图片加载成功之后, 怎么去更新ImageView?一般来讲,有两种处理方式,第一种:将ImageView传递给AsyncTask,task执行完之后,直接ImageView设置bitmap,第二种:Task执行完毕之后,将Bitmap存储在缓存里,通知主线程的view,进行数据更新。

    将ImageView传递给AsyncTask

    要求

    1. ListView或者GridView会复用ImageView,例如pos为4的ImageView4开启了一个AsyncTask,用户滚动到了pos为8的位置,复用了ImageView4,即使这个时候AsyncTask更新完了,但是也不能去更新ImageView4。
    2. AsyncTask不能阻止ImageView的内存释放,例如当用户离开这个页面的时候,应该销毁界面,AsyncTask应当避免造成内存泄露
    3. 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);
            }
        }
  • 相关阅读:
    实现简易赈灾物资发放登记系统---练习
    数据访问-----ADO.NET 练习2
    数据访问-----ADO.NET 练习1
    面向对象(3)继承
    面向对象(2)
    面向对象(1)
    JavaScript 内容串联 ---Document---四、五和正则表达式。
    JavaScript 内容串联 ---Document
    document--操作相关元素(js简短汇总3)
    js--document对象操作内容(js简短汇总2)
  • 原文地址:https://www.cnblogs.com/idealgrass/p/4309644.html
Copyright © 2011-2022 走看看