图片加载AsyncTask并发问题
在列表控件中使用AsycnTask加载图片时,会带来并发问题。
如果每个子视图都触发一个AsyncTask,因为AsyncTask内部是一个线程池,并发触发时,不能确保每个子视图的AsyncTask都进入了队列,而且异步任务的完成顺序和启动顺序也不一定一致。
Multithreading For Performance这篇文章提供了一种方法。
主要方案如下:
通过定制一个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();
}
}
ListView显示一个ImageView,并开始下载之前,判断是否有另一个AsyncTask已经与该ImageView绑定
- 如果存在一个Task,并且它的任务就是当前ImageView的任务,则不会新建一个AsyncTask去下载
- 如果不存在,或者存在的任务执行的下载不同于当前的任务,就取消当期的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;
}
- 使用:在加载图片时:使用
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);
}
图片加载AsyncTask并发问题的更多相关文章
- [原]Android官方图片加载利器BitmapFun解析
通过BitmapFun在项目中使用,结合代码了解一下BitmapFun加载图片的原理,以及最佳使用实践.本文说明不包括BitmapFun的缓存部分. Android开发在使用ListView和Grid ...
- Android中常见的图片加载框架
图片加载涉及到图片的缓存.图片的处理.图片的显示等.而随着市面上手机设备的硬件水平飞速发展,对图片的显示要求越来越高,稍微处理不好就会造成内存溢出等问题.很多软件厂家的通用做法就是借用第三方的框架进行 ...
- imagepool前端图片加载管理器(JavaScript图片连接池)
前言 imagepool是一款管理图片加载的JS工具,通过imagepool可以控制图片并发加载个数. 对于图片加载,最原始的方式就是直接写个img标签,比如:<img src="图片 ...
- Android图片加载库:最全面的Picasso讲解
前言 上文已经对当今 Android主流的图片加载库 进行了全面介绍 & 对比 如果你还没阅读,我建议你先移步这里阅读 今天我们来学习其中一个Android主流的图片加载库的使用 - Pica ...
- 一起写一个Android图片加载框架
本文会从内部原理到具体实现来详细介绍如何开发一个简洁而实用的Android图片加载缓存框架,并在内存占用与加载图片所需时间这两个方面与主流图片加载框架之一Universal Image Loader做 ...
- Android项目框架之图片加载框架的选择
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 从Android爆发以后,自定义的控件如EditTextWithDelete.ActionBar.P ...
- Android批量图片加载经典系列——采用二级缓存、异步加载网络图片
一.问题描述 Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取.再从文件中获取,最后才会访问网络. ...
- Android Handler 异步消息处理机制的妙用 创建强大的图片加载类(转)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38476887 ,本文出自[张鸿洋的博客] 最近创建了一个群,方便大家交流,群号: ...
- 图片加载之Picasso使用
简介 Picasso是Square公司开源的一个Android图形缓存库,可以实现图片下载和缓存功能. 主要有以下一些特性: 在Adapter中回收和取消已经不在视野范围图片资源的加载,防止可能出现的 ...
随机推荐
- CodeIgniter-CI之MySQL
首先我们需要进行一下配置,这里需要修改的文件为application目录下的config目录下的database.php文件,我们修改相应的配置项,比如这里是我的配置情况: 通常我们在操作数据库之前, ...
- js:重复输出字符串中字符
复习了 重复输出一个字符串后, 重复输出一个字符串是 比如给定 str:abc num:3 要求输出 abcabcabc 文章链接:https://www.cnblogs.com/mobu/p/98 ...
- Linux—Ubuntu14.0.5 修改gitlab管理员的密码
1. 在root用户下,执行 gitlab-rails console production #进入gitlba控制台 2.获得用户数据,修改用户密码 [root@svr34 bin]# gitlab ...
- Python学习笔记之函数
这篇文章介绍有关 Python 函数中一些常被大家忽略的知识点,帮助大家更全面的掌握 Python 中函数的使用技巧 1.函数文档 给函数添加注释,可以在 def 语句后面添加独立字符串,这样的注释被 ...
- jetty+httpClient使用
背景: 看了https://www.cnblogs.com/donlianli/p/10954716.html这篇文章之后,突然发现自己的知识面太窄了,连这些几乎可以说基础的工具都没怎么用过,于是决定 ...
- HRBUST 1214 方格取数
方格取数 Time Limit: 1000ms Memory Limit: 65535KB This problem will be judged on HRBUST. Original ID: 12 ...
- GetBulkRequest PDU的应用
http://blog.csdn.net/wenph2008/article/details/16821617
- asp.net常用容器
autofac就是ioc的第三方的IOC容器 unity也是IOC容器 掌握这两个容器就可以了,非常简单
- HDU 5175
我想了很久了,后来还是把N分解质因数,枚举各种组合,反正也不多吧,按题目条件,然后就过了. #include <cstdio> #include <iostream> #inc ...
- 命令行使用Eclipse的debug签名失败“找不到 xx.keystore证书链”
1.debug签名位置 2.查看debug.keystore具体信息 3.使用命令行签名 注意:debug签名password为android 4.出错原因是签名的别名写错,应为androiddebu ...