当异步提取时,如何避免列表视图中的多位图实例化?

时间:2012-08-13 13:45:56

标签: android listview

问题

我遇到了位图问题以及listview多次在每个位置调用getView()的行为。

我的列表只包含位图,并从远程位置异步获取它们。现在,当显示列表视图时,由于每个位置调用getView()大约4次(没有滚动),它将为同一位置实例化4个不同的位图实例(并且只使用一个......),这会导致内存错误。

我尝试了什么

我已经有了位图缓存,但这是在第一次获取图像之前发生的。例如。 listView打开,对位置0的位图发出4个请求,一旦到达,将位图保存在缓存中。在此之后,问题得以解决。但我的问题是关于第一次创建4位图(对于项目0,项目1,项目2,项目3 - > 16位图,我只需要4位)。

我已经尝试了一些策略来解决这个问题,比如实现一个“等待”的imageViews列表,只获取一个,然后为所有等待的设置位图,但是这会产生新的问题而且也很难同步。

我还尝试添加一个列表字段,其中列表视图已经被取出,为了获取和设置一次,getView()似乎每次都生成一个不同的图像视图(或类似)(我正在回收convertView,但无论如何),因为我以空位置结束(尽管所有位图都是在其中一个图像视图中获取,实例化和设置的)。 为了解决这个问题,我使用了一个map位置,它将位置映射到ImageView的List,并将位图设置为所有需要调用一个位置的imageViews。应该工作,但它也没有。在大多数位置,我得到正确的位图,但是,例如,在列表的第一个位置,我从最后一个可见位置得到位图(我可以看到它快速切换,首先它显示位置0的位图,然后是1,然后2,然后3 -my最后一个可见的位置 - )。如果我关闭回收(每次充气convertView),这就解决了,但这当然不是一个好的解决方案。

我想到的另一种可能性,但感觉就像一个糟糕的解决方案(就像其他的一样),就是预先获取位图,因此,在列表滚动之前,我已经在缓存中找到了下一个x位图。这将与scrolllistener结合使用,其中滚动导致获取下一个x项并将它们放入缓存中。因此,当列表调用getView()时(无论多么偏离),它总是从缓存中获取相同的预取位图实例。)

我不应该是唯一一个遇到此问题的人,因为从网络上获取的位图的列表/网格视图非常常见......

任何解决方案?提前谢谢。

1 个答案:

答案 0 :(得分:0)

我注意到这种行为只发生在第一个可见的项目上。当我向下滚动列表直到结束时,它仍然会为第一个项目调用getView(),但对于其余项目,它只调用一次。

对于第一个列表项,预加载位图是有意义的,因此当列表调用getView()时它们已经在内存中,并且不会被实例化。现在我改进了应用程序其他部分的内存使用量,这样这个问题不会导致设备崩溃。