有人可以告诉我如何为异步制定一个好的机制。下载用于 ListView/GridView 的图像?有很多建议,但每一个都只考虑典型需求的一小部分。
下面我列出了一些我和我的同事无法同时满足的合理因素(要求或需要考虑的事项)。
我不是要求代码(尽管它会受到欢迎),只是一种按照描述管理位图的方法。
- 没有重复的下载器或位图
- 取消下载/分配不再需要或可能会自动删除的图像(SoftReference 等)
- 注意:一个适配器可以有多个相同 ID 的视图(对 getView(0) 的调用非常频繁)
- 注意:不能保证视图不会丢失而不是回收(考虑 List/GridView 调整大小或按文本过滤)
- 视图和数据/逻辑的分离(尽可能)
- 没有为每次下载启动单独的线程(UI 明显变慢)。使用队列/堆栈(BlockingQueue?)和线程池,或类似的......但如果活动停止,则需要结束它。
- 清除距离列表/网格中当前位置足够远的位图,最好仅在需要内存时
- 在要丢弃的每个位图上调用 recycle()。
- 注意:外部存储器可能不可用(完全或始终),如果使用,应尽快清除(仅在此处下载的图像)(考虑 Android 的 Activity 破坏/重新创建)
- 注意:可以更改数据:删除条目(多选和删除)和添加(在后台线程中)。应该保留已经下载的位图,只要它们链接的条目仍然存在。
- setTextFilterEnabled(true)(如果基于ArrayAdapter的机制,会影响数组索引)
- 可在 ExpandableList 中使用(影响缩略图的显示顺序)
- (可选)下载位图时,仅刷新相关的 ImageView(列表项可能非常复杂)
请不要张贴个别点的答案。我的问题是,我们越关注某些方面,其他方面就越模糊,类似于海森堡。
每一个都增加了一个难度维度,尤其是Bitmap.recycle,需要在运行时和Activity销毁时调用(注意onDestroy,甚至onStop都可能不会调用)。
这也排除了对 SoftReferences 的依赖。
这是必要的,否则即使在清空位图后,即使在尝试捕获(强制受控的 OutOfMemory)中进行任意数量的 gc、睡眠(甚至 20 秒)、yield 和巨大的数组分配后,我也会得到 OutOfMemoryError。
我已经重新采样位图。