android 多线程和异步加载图片,对Android中的多图片异步加载的重新思考

订阅

现在想来,Android SDK把并行执行改为串行执行也并不无道理。

对本文有任何问题,可加我的个人微信询问:kymjs123

起因

不知道大家有没有发现,在2.0.4.1(37)版本之前的开源中国客户端首次加载图片的时候,会很慢,尤其是动弹列表中的图片。甚至网速慢的时候感觉图片根本加载不出来。

原因是在下载网络图片的时候使用了多线程并发执行的方式,什么意思呢,也就是开启了多个线程同时去下载多张图片。按照正常的思维来想,做图片加载操作使用多线程,这应该是很正常的,因为在我们的思维中,多线程资源利用率更高,程序响应更快。

举个例子:一个应用程序需要从本地文件系统中读取和处理文件的情景。比方说,从磁盘读取一个文件需要5秒,处理一个文件需要2秒。处理两个文件则需要

5秒读取文件A

2秒处理文件A

5秒读取文件B

2秒处理文件B

---------------------

总共需要14秒

从磁盘中读取文件的时候,大部分的CPU时间用于等待磁盘去读取数据。在这段时间里,CPU非常的空闲。它可以做一些别的事情。通过改变操作的顺序,就能够更好的使用CPU资源。看下面的顺序

5秒读取文件A

5秒读取文件B + 2秒处理文件A

2秒处理文件B

---------------------

总共需要12秒

CPU等待第一个文件被读取完。然后开始读取第二个文件。当第二文件在被读取的时候,CPU会去处理第一个文件。记住,在等待磁盘读取文件的时候,CPU大部分时间是空闲的。总的说来,CPU能够在等待IO的时候做一些其他的事情。这个不一定就是磁盘IO。它也可以是网络的IO,或者用户输入。通常情况下,网络和磁盘的IO比CPU和内存的IO慢的多。

既然采用多线程并发执行可以提高CPU的利用率,可是为什么反倒用在Android的图片加载上变得更慢了?

看到这里,你应该已经想到原因了。就好像我们写代码,一个人同时写两个Android应用,并发布上线。假设应用发布不需要上线审核,且A与B的功能几乎相同。如果我们去先写应用A的一个功能,当A某一个功能写完的时候再去写应用B相同的功能,那么写起来自然是要快很多。这就是并发执行,同时去执行A与B。但是这样A与B完成的总时间是缩短了,可以单个A应用完成的时间却被拉长了。因为写到一半的时候被迫去完成B应用。

所以这也是为什么你会发现37版本之前的OSC客户端图片几乎是同时出来的。

回到Android上,我之前的博客曾讲过:AsyncTask在android2.3的时候线程池是一个核心数为5线程,队列可容纳10线程,最大执行128个任务,这存在一个问题,当你真的有138个并发时,即使手机没被你撑爆,那么超出这个指标应用绝对crash掉。 后来升级到3.0,为了避免并发带来的一些列问题,AsyncTask竟然成为序列执行器了,也就是你即使你同时execute N个AsyncTask,它也是挨个排队执行的。 这一点请同学们一定注意,AsyncTask在3.0以后,是异步的没错,但不是并发的。不知道的同学可以去看看《Thread并发请求封装——深入理解AsyncTask类》,《一套完善的Android异步任务类》

现在想来,Android SDK把并行执行改为串行执行也并不无道理。

也许你会担心,那改回串行以后会不会又出现同时加载129个图片的时候崩溃的问题。当然,是不会的。在图片加载的时候已经做了下载任务取消的设计,在listView中加载图片的时候,如果滚动出这一屏,图片的下载任务会马上停止,而去加载新的图片下载。总不会一个屏幕就显示129张图吧。

/**

* 取消一个下载请求

*

* @param view

*/

public void cancle(View view) {

for (BitmapWorkerTask task : taskCollection) {

if (task.imageView.equals(view)) {

task.cancelTask();

taskCollection.remove(task);

break;

}

}

}

了解更多有深度技术的文章,与移动端、大前端未来方向的认知,前往订阅 开源实验室小专栏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值