zoukankan      html  css  js  c++  java
  • 图片加载AsyncTask并发问题

    在列表控件中使用AsycnTask加载图片时,会带来并发问题。

    如果每个子视图都触发一个AsyncTask,因为AsyncTask内部是一个线程池,并发触发时,不能确保每个子视图的AsyncTask都进入了队列,而且异步任务的完成顺序和启动顺序也不一定一致。

    Multithreading For Performance这篇文章提供了一种方法。

    主要方案如下:

    1. 通过定制一个BitmapDrawable,让ImageView储存当前AsyncTask的引用(弱引用)

      BitmapLoadTask,一个加载图片的AsyncTask,可以执行从网络、文件加载图片

    class AsyncDrawable extends BitmapDrawable {
        private final WeakReference<DownloadTask> downloadTaskWeakReference;
        
        AsyncDrawable(BitmapLoadTask downloadTask) {
            this.downloadTaskWeakReference = new WeakReference<>(downloadTask);
        }
        public DownloadTask getDownloadTask() {
            return downloadTaskWeakReference.get();
        }
    }
    
    1. ListView显示一个ImageView,并开始下载之前,判断是否有另一个AsyncTask已经与该ImageView绑定

      1. 如果存在一个Task,并且它的任务就是当前ImageView的任务,则不会新建一个AsyncTask去下载
      2. 如果不存在,或者存在的任务执行的下载不同于当前的任务,就取消当期的Task,然后新建一个。

      下载时判断:

        public void loadBitmap(String url, ImageView imageView) {
            if (shouldNewTaskToLoad(url, imageView)) {
                final BitmapLoadTask bitmapLoadTask = new BitmapLoadTask(imageView);
                final AsyncDrawable asyncDrawable = new AsyncDrawable(bitmapLoadTask);
                imageView.setImageDrawable(asyncDrawable);
                bitmapLoadTask.execute(url);
            }
        }
    ```java
        
        判断的逻辑:
    ```java
    public static boolean shouldNewTaskToLoad(String url, ImageView imageView) {
            if (imageView != null) {
                AsyncDrawable asyncDrawable = (AsyncDrawable) imageView.getDrawable();
                if (asyncDrawable != null) {
                    BitmapLoadTask bitmapLoadTask = asyncDrawable.getDownloadTask();
                    if (bitmapLoadTask != null) {
                        //如果当前要下载的图片的地址与ImageView中储存的Task下载的地址不想等
                        if (url == null || (!url.equals(bitmapLoadTask.url))) {
                            bitmapLoadTask.cancel(true);
                        } else {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    
    1. 使用:在加载图片时:使用setImageDrawable将AsyncTask与ImageView关联
        if (shouldNewTaskToLoad(url, imageView)) {
           final BitmapLoadTask bitmapLoadTask = new BitmapLoadTask(imageView);
           final AsyncDrawable asyncDrawable = new AsyncDrawable(bitmapLoadTask);
           imageView.setImageDrawable(asyncDrawable);
           bitmapLoadTask.execute(url);
            }
    
  • 相关阅读:
    【前端积累】点击链接切换图片显示
    【Spring Boot && Spring Cloud系列】构建Springboot项目 实现restful风格接口
    【JavaEE企业应用学习记录】验证配置
    optiontransferselect例子
    javascript面向对象(给对象添加属性和方法的方式)
    JavaBean toString方式
    JavaScript 字符串操作
    SQL AND和OR求值顺序
    dom4j解析XML
    SQL使用总结-like,MAX,MIN
  • 原文地址:https://www.cnblogs.com/jiy-for-you/p/7282029.html
Copyright © 2011-2022 走看看