我看到一大堆建议,但没有一个(我发现)考虑到所有因素,这些因素是:
- 异步下载,没有重复(下载器和位图),取消下载/分配无论如何都不再需要的图像
- 一个适配器可以有多个相同 ID 的视图(对 getView(0) 的调用非常频繁)
- 不能保证视图不会丢失而不是被回收(考虑 List/GridView 调整大小或按文本过滤)
- 视图和数据/逻辑的分离(尽可能)
- 没有为每次下载启动一个单独的线程(UI 明显变慢)。使用队列/堆栈(LinkedBlockingQueue?)和线程池,或类似的......但如果 Activity 被销毁,则需要结束它。
- 清除距离列表/网格中当前位置足够远的位图,最好仅在需要内存时
- 在要丢弃的每个位图上调用 recycle()。
- 外部存储器可能不可用(完全或始终),如果使用,应尽快清除(仅在此处下载的图像)。还要考虑 Android 的 Activity 破坏/娱乐。
- 正在更改的数据:删除条目(在列表中选择、删除按钮、立即刷新)并在后台线程中添加(按需刷新列表)。应该保留已经下载的位图,只要它们链接的条目仍然存在。
- (可选)不要依赖 notifyDataSetChanged (afaik 刷新所有可见的、可能非常复杂的列表项)来更新单个 ImageView
- setTextFilterEnabled(true) (如在 ArrayAdapter 中。它的 Filterable 实现替换了其他 Adapter 方法可见的数据数组,因此更改了视图的索引,因此它们不能用作链接到位图的 ID)。
- 可在 ExpandableList 中使用(影响缩略图的显示顺序)
如果已经回答,请原谅我。我已经搜索了几个月,但没有找到解决方案。
要求在我看来是合理的,但每一个都增加了一个难度维度,尤其是Bitmap.recycle,需要在运行期间和Activity销毁时调用(注意onDestroy,甚至onStop都可能不会调用)。
这也排除了对 SoftReferences 的依赖,它本来可以处理其他一些问题。
是的,这是必要的,或者即使在尝试捕获中的任意数量的 gc、睡眠(甚至 20 秒)、产量和巨大的数组分配(强制控制的低内存情况)之后,我也会得到 OutOfMemoryError。
搜索“OutOfMemoryError:位图大小超出 VM 预算”或“android 位图回收”。
是的,我正在重新采样位图。