图片加载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中回收和取消已经不在视野范围图片资源的加载,防止可能出现的 ...
随机推荐
- centos7关闭防火墙以及查看防火墙状态
1.关闭firewall:systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止fir ...
- [jzoj 5776]【NOIP2008模拟】小x游世界树 (树形dp)
传送门 Description 小x得到了一个(不可靠的)小道消息,传说中的神岛阿瓦隆在格陵兰海的某处,据说那里埋藏着亚瑟王的宝藏,这引起了小x的好奇,但当他想前往阿瓦隆时发现那里只有圣诞节时才能到达 ...
- 企业版 Linux 附加软件包(EPEL)
企业版 Linux 附加软件包(以下简称 EPEL)是一个由特别兴趣小组创建.维护并管理的,针对 红帽企业版 Linux(RHEL)及其衍生发行版(比如 CentOS.Scientific Linux ...
- 9.简单理解ES分布式
主要知识点: 1.Elasticsearch对复杂分布式机制的透明隐藏特性 2.Elasticsearch的垂直扩容与水平扩容 3.增减或减少节点时的数据rebalance 4.master节 ...
- Docker在WIN7上的配置
为什么使用Docker Toolbox Docker在Windows上使用有两种方式,一是利用VirtualBox建立linux虚拟机,在linux虚拟机中安装docker服务端和客户端,二是利用Wi ...
- WebFont与页面font-icon图标研究
当你打开(绝大部分)网站,页面上将会有许多形形色色的小图标(icon),适当的icon的可以达到一图胜千言的目的,使网页的表现效果更佳. 关于页面icon的制作,比较传统的方法是,让设计师去设计一个个 ...
- 一个asp+ACCESS省市二级联动菜单程序
<%dim conndim connstron error resume nextconnstr="DBQ="+server.MapPath("test.mdb&q ...
- oracle批量更新
oracle批量更新 学习了:http://blog.csdn.net/zkcharge/article/details/50855755 statement.addBatch(); statemen ...
- C++开发人脸性别识别教程(12)——加入性别识别功能
经过之前几篇博客的解说,我们已经成功搭建了MFC应用框架,并实现了主要的图像显示和人脸检測程序,在这篇博文中我们要向当中加入性别识别代码. 关于性别识别,之前已经专门拿出两篇博客的篇幅来进行解说.这里 ...
- Spring JDBC数据库开发
针对数据库操作,Spring框架提供了JdbcTemplate类. 1.Spring JDBC的配置 创建配置文件applicationContext.xml,添加如下代码: <!--配置数据源 ...