我必须相信,一旦不再需要它,就有一种方法可以从内存中清除图像数据,但是尽管进行了详尽的搜索,我还是找不到解决方案。stack 和 google android dev list 都充满了关于 OOM 错误的问题,特别是“位图大小超出 VM 预算”,但我仍然没有看到明确的答案。
我了解设备存在硬内存限制,并且我了解加载和显示或缓存大量图像数据是不现实的,但应该避免丢弃不再需要的数据。
例如,想象一下这个非常基本的假设应用程序,它模拟了本地图库应用程序的许多行为:
- 允许用户细读来自远程服务器的图像的图像库。
- 该服务器上可能有任意数量的图像。
- 该应用程序一次显示 1 张图像,并允许用户通过按钮按下或滑动一次返回或前进 1 张图像。
- 一次最多渲染 3 张图像(因此用户可以在滑动时立即看到当前图像左侧或右侧的一张)。应丢弃所有其他图像数据。
- 使用 URL.openStream 和 Drawable.createFromStream 或 BitmapFactory.decodeStream 加载图像。流已适当关闭。
- 图像在获取之前在服务器上调整大小。
- 加载发生在 AsyncTasks 中。不再需要的任务(由于从具有不完整任务的图像中移开)被取消。AyncTask 中的任何引用都是 WeaklyReferenced。
- 当不再需要任何图像时,将通过以下方式“清除”它:
- getBackground().setCallback(null)
- 侦听器设置为 null
- setImageDrawable/位图(空)
- 删除视图
这个简单的结构考虑到了我所知道的所有建议做法,在某些时候不可避免地会因 OOM 错误而崩溃。使用 BitmapFactory.Options inSampleSize 和 inPreferredConfig 将延迟不可避免的情况,但不会永远延迟,并且会以图像质量为代价。在此示例中,我使用了远程图像,但是存储在 /assets/ 或内部存储器等中的图像存在问题。
我的感觉是,如果我们可以在某一点显示 X 数量的图像数据,并且我们采取所有步骤从内存中删除该图像数据,我们应该能够稍后显示相同数量的数据,而不必补偿已经存在的数据。以前发生过。
由于关于这个问题的问题数量众多,我希望有一个标准的解决方案记录在案,但如果有的话,我找不到它。我看过 Romain Guy 发布的答案,他在其他方面似乎对他的知识非常慷慨,并且在社区中很活跃,他说的是“简单。不要使用太多内存”。好的。告诉我怎么做。
我还应该提到 System.gc 对此没有任何帮助。我也知道 bitmap.recycle,但除非我弄错了,否则不能以这种方式使用它。
我错过了一些基本的东西吗?一旦不再使用图像数据,有没有办法丢弃它?上面缺少什么来创建一个简单的照片库?假设内置画廊应用程序使用框架而不是 NDK,我想必须有一种方法......
蒂亚。
/这个问题也已经发布在 android developer google group list 上。