1

问题

我对位图和列表视图在每个位置多次调用 getView() 的行为有疑问。

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

我试过的

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

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

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

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

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

有什么解决办法吗?提前致谢。

4

1 回答 1

0

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

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

于 2012-08-14T22:38:35.303 回答