ListView异步图像加载策略

时间:2011-06-26 18:56:52

标签: android listview

我目前有一个带有自定义适配器的ListView,它可以异步地获取描述行内容的信息。每行的一部分是图像URL,我打算异步下载然后显示。

我目前计划下载这些图片的策略是:

  • 保留对下载的Bitmap对象的软引用缓存。
  • 调用getView()并且位图位于缓存中时,直接设置ImageView的位图。
  • 如果位图不在缓存中,请在单独的线程中开始加载,在下载完成后将其添加到缓存并在适配器上调用notifyDataSetChanged()。

我还打算在调用拥有ListView的onDestroy() - 方法(或者甚至可能在onPause() - 方法中)的Activity对象时杀死挂起的下载,但最重要的是我要杀死挂起的图像的下载当行离开屏幕时。我可能实际上只是在短暂延迟后取消下载,因此如果该行再次快速进入屏幕,则可以在不浪费带宽的情况下恢复下载。

但是,我不确定一些事情:

  • 什么是检测行何时离屏的最佳方法,以便我可以取消下载?
  • 在下载完成后调用notifyDataSetChanged()是最好的办法还是有更好的方法?

此外,对整个战略的任何评论都将受到赞赏。

3 个答案:

答案 0 :(得分:8)

我不认为真的需要调用notifyDataSetChanged()......我会这样做:

  • 创建/更新时在视图中将URL存储为标记
  • 在下载程序线程(异步任务???)中注册一个侦听器,以便下载保持对视图和URL的引用
  • 每当异步下载图像时,我在视图中检查TAG,如果匹配 - 我会更新ImageView(在UI线程中这很重要,但是在使用异步任务时,会给出它)。图像也应存储在SD卡上(每次请求URL时,都应检查是否已下载)。
  • 每当getView()重用视图(传递的视图不为空)时,我会检查标记(旧网址),将其替换为新网址并取消下载oldURL。

我认为它几乎就是它(某些极端情况可能会发生)......

答案 1 :(得分:3)

我使用getFirstVisible和getLastVisible AdapterView属性来检测可见行,并将请求放在固定大小的堆栈中。

我的项目是开源的,如果你想使用它,它有一个最宽松的许可证: https://github.com/tbiehn/Android-Adapter-Image-Loader

-Travis

答案 2 :(得分:0)

我发现在Foursquared源代码中管理/获取远程资源非常有帮助:

http://code.google.com/p/foursquared/source/browse/main/src/com/joelapenna/foursquared/util/RemoteResourceManager.java

它将图像缓存在磁盘上并处理所有3个功能请求。请参阅适配器以了解如何使用它。

当一行关闭时取消下载,你必须自己处理