listView convertView缓存机制 & 异步加载图片 问题剖析

listView convertView缓存机制 & 异步加载图片 问题剖析

     先介绍下 listView的convertView缓存机制 & 异步加载图片:

     convertView缓存机制: 我们假设一个屏幕一次显示8个item,当第9个item划进屏幕时,ListView对adapter说,返给我一个view,我要显示。adapter调用getView()方法,由于使用了convertView缓存机制,getView(),会在上一次new 出来的8个itemview中取出第一个 itemview (这时因为不显示了,listview将其变成了convertview),并给了listview作为 第9个item的view。
     异步加载图片:如果我们不适用异步加载图片,那么必须要在每次getview()返回一个view前把view的iamgeview设置好了图片再返回给Listview,这意味着我必须等网络下载好了这个图片我才能返回给listview一个item,很明显,下滑 效果是屏幕卡顿的半天没反应。但是使用异步加载,先让adapter返回一个view,view的iamgeview我先不确定,并开启一个新线程去下载图片,等图片下载好了,再去更新到这个view的imageview。当然了,一般只需要异步加载图片,而文字信息默认认为已经取得了,当然文字也是可以异步加载的。

    但是,当我们使用了 listView在通过 convertView缓存机制 & 异步加载图片时,若快速滑动屏幕,会发生图片闪顿2次以上的错图最后才能正确显示图片的现象。我们来剖析原因:     
    之所以会在下滑后,图片显示出一个之前的错图,是因为convertview的缓存,这个convertview的图片还是保持着上一次的图片,然而我这里的新线程还没来得及下载好并更新到这个imageview,你的老图片就已经显示上去了。所以造成了第一次的错图。但是这里不会出现闪!
    然后快速下滑,发现第一个错图就要被正确的第二张图显示替换时,我又把屏幕下滑了,所以我又换了个图,第二次又错图了。我假设每个图片下载需要1s,由于我使每个异步线程人工阻塞了1s,那么上来有8个异步线程在运行(编号1-8),如果1s之内下滑了ListView比如说下滑了8个,那么新更新的8个item还是用的以前老view(不是新new出来的),并且又开启了8个异步线程(编号9-16)。因为之前显示了是老的图片。然后1-8号异步线程运行完毕,更新ImageView,所以出现了一次闪,紧跟着9-16异步线程运行完毕,又更新imageView,又出现了一次闪。最终显示正确结果。这就是下滑时先显示默认图片,再闪一下错误图片,最后闪一下正确图片的本质过程。这次是另一种错误原因。

    所以,我们为了解决问题,分两步走:
         1,在getview返回一个convertView之前,我把imageview设置为一个固定的图片(ic_launcher),覆盖掉convertview的老错图,这样就不会在显示时造成错图尴尬了。所以 convertView缓存机制造成的错图原因得到解决,因为: 缓存造成的错图是无法避过的········
         2.在 把imageview设置为一个固定的图片(ic_launcher),覆盖掉convertview的老错图之后,我为 ImageView设置了一个tag(url),tag里放的是一个唯一标识url,并且在异步线程里传入url,当线程下载好了后,先判断iamgeview的tag是不是我下载的这个url,如果是,说明主人还没有滑动,还在等我加载图片,那么我赶紧显示上去;如果tag!=url了,说明主人早已又滑了一段,我所在的convertView又被替换了一次,所以我还是别显示了!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值