您的位置:首页 > 其它

Listview异步加载缓存图片,解决快速滑动问题

2013-06-09 10:31 501 查看
搜了大量资料见的大多避免oom的方法有压缩和缓存,这里也采用这2种方法吧。

压缩就不用我说了,缓存图片我用的LruCache这个类,本身已经实现了同步,这里就不再多说什么了,不知道的同学可以去研究下,这里主要想讲的的异步加载的时机。在这里写下也只是分享下我的体验,欢迎拍砖~~~

大家做过这个的都碰到过,快速滑动时由于大量异步加载和message消息的等待排队,当快速滑动停止时要等好一会才能轮到当前可视item图片的加载显示,如何避免这个问题?

那就从问题来源入手:快速滑过的那些item图片可以先暂不加载,等到用户正常划过时再去加载不迟~~~

我的代码思路:在getView方法里面判断Listview的滑动状态,如果正在滑动,则不加载,但要保存此时的图片信息,等到适当机会再去加载,否则异步加载图片~~~

实现Listview状态的标识,代码:

?
代码片段,双击复制

isBusy用来标识Listview是否处在滑动状态,asyncLoading()方法下面会说到

现在知道了当前listview的滚动状态,那么现在就开始在getview里面加载资源吧:

?
代码片段,双击复制

代码的注释很清楚了,我在这里再说下,如果当前listview不在滑动状态时,正常加载图片,否则就记录当前的图片信息,存放到一个集合中,等待适当的机会去加载,什么时候适当呢?那就是listview不在滑动的时候,即isbusy=false时。

那回过头来看上面出现过的asyncLoading()这个方法吧

?
代码片段,双击复制

注释很清楚了,也就不再说了。

总之,demo实现了这样一个效果,每个item的图片都属于自己,没有重用(因为同一张图片每次都是重新加载到内存的),当正常滑动listview时,则正常加载图片,当快速滑动时,只加载listview停下后可视item的图片,这就避免了等待啦,因为之前被滑过item的图片没有被异步加载哦~~欢迎提出意见,大家一起学习~~~

当然,真正的应用是不只在getview方法里面去加载的,因为滑动过后才会去加载,体验效果会很差,这里只是学习用

存在错位bug:

你会发现有时同一张图片会连续变动1、2次,甚至更多次,那是因为convertView缓存的缘故,

比如消息队列中有消息要通知刷新position=10,16,22这3个图片的位置,而这三个item恰好使用同一个convertView,所以他们也是使用的同一个ImageVIew

此时position=22的item是可视的

那么这个ImageVIew.setImageBitmap()的方法会被连续调用3次

导致你们会看到图片连续变动

这个bug在本demo中很好解决,2个方法:

1:就是判断当前可视的item位置再去设

2:在手动发送message之前清空消息队列(这种方法适合于一定要是非常快速滑动的那种,因为listview稍微滑下就会处于busy状态,此时正常加载的position还是可视的)

提出问题:如果一开始就去加载全部图片后缓存,而不是在getview里面开线程去加载图片,那么如何通知到对应的图片UI更新以及错位呢?这过程会发生什么问题?你可以亲自动手实现下,提醒下加载图片是耗时的哦~~~

tip:我自己碰到了message消息过期的问题,正在解决中。。

奉上代码:主要是图片大,代码就一个类



BitmapCache.rar
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: