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);
            }
        }
  • 相关阅读:
    Maidsafe-去中心化互联网白皮书
    The Top 20 Cybersecurity Startups To Watch In 2021 Based On Crunchbase
    Top 10 Blockchain Security and Smart Contract Audit Companies
    The 20 Best Cybersecurity Startups To Watch In 2020
    Blockchain In Cybersecurity: 11 Startups To Watch In 2019
    004-STM32+BC26丨260Y基本控制篇(阿里云物联网平台)-在阿里云物联网平台上一型一密动态注册设备(Android)
    涂鸦开发-单片机+涂鸦模组开发+OTA
    000-ESP32学习开发-ESP32烧录板使用说明
    03-STM32+Air724UG远程升级篇OTA(阿里云物联网平台)-STM32+Air724UG使用阿里云物联网平台OTA远程更新STM32程序
    03-STM32+Air724UG远程升级篇OTA(自建物联网平台)-STM32+Air724UG实现利用http/https远程更新STM32程序(TCP指令,单片机程序检查更新)
  • 原文地址:https://www.cnblogs.com/idealgrass/p/4309644.html
Copyright © 2011-2022 走看看