2

我必须相信,一旦不再需要它,就有一种方法可以从内存中清除图像数据,但是尽管进行了详尽的搜索,我还是找不到解决方案。stack 和 google android dev list 都充满了关于 OOM 错误的问题,特别是“位图大小超出 VM 预算”,但我仍然没有看到明确的答案。

我了解设备存在硬内存限制,并且我了解加载和显示或缓存大量图像数据是不现实的,但应该避免丢弃不再需要的数据。

例如,想象一下这个非常基本的假设应用程序,它模拟了本地图库应用程序的许多行为:

  1. 允许用户细读来自远程服务器的图像的图像库。
  2. 该服务器上可能有任意数量的图像。
  3. 该应用程序一次显示 1 张图像,并允许用户通过按钮按下或滑动一次返回或前进 1 张图像。
  4. 一次最多渲染 3 张图像(因此用户可以在滑动时立即看到当前图像左侧或右侧的一张)。应丢弃所有其他图像数据。
  5. 使用 URL.openStream 和 Drawable.createFromStream 或 BitmapFactory.decodeStream 加载图像。流已适当关闭。
  6. 图像在获取之前在服务器上调整大小。
  7. 加载发生在 AsyncTasks 中。不再需要的任务(由于从具有不完整任务的图像中移开)被取消。AyncTask 中的任何引用都是 WeaklyReferenced。
  8. 当不再需要任何图像时,将通过以下方式“清除”它:
    • getBackground().setCallback(null)
    • 侦听器设置为 null
    • setImageDrawable/位图(空)
    • 删除视图

这个简单的结构考虑到了我所知道的所有建议做法,在某些时候不可避免地会因 OOM 错误而崩溃。使用 BitmapFactory.Options inSampleSize 和 inPreferredConfig 将延迟不可避免的情况,但不会永远延迟,并且会以图像质量为代价。在此示例中,我使用了远程图像,但是存储在 /assets/ 或内部存储器等中的图像存在问题。

我的感觉是,如果我们可以在某一点显示 X 数量的图像数据,并且我们采取所有步骤从内存中删除该图像数据,我们应该能够稍后显示相同数量的数据,而不必补偿已经存在的数据。以前发生过。

由于关于这个问题的问题数量众多,我希望有一个标准的解决方案记录在案,但如果有的话,我找不到它。我看过 Romain Guy 发布的答案,他在其他方面似乎对他的知识非常慷慨,并且在社区中很活跃,他说的是“简单。不要使用太多内存”。好的。告诉我怎么做。

我还应该提到 System.gc 对此没有任何帮助。我也知道 bitmap.recycle,但除非我弄错了,否则不能以这种方式使用它。

我错过了一些基本的东西吗?一旦不再使用图像数据,有没有办法丢弃它?上面缺少什么来创建一个简单的照片库?假设内置画廊应用程序使用框架而不是 NDK,我想必须有一种方法......

蒂亚。

/这个问题也已经发布在 android developer google group list 上。

4

2 回答 2

3

通过我与Prime的合作,我发现了一些技巧,其中一个你没有提到。inPurgeable当您解码您的位图时,请确保inInputShareable在您的BitmapFactory.Options. 这会有所帮助,但我建议您查看我在 Prime 中的图像加载实现。我在所有产品中都使用它,没有任何内存问题。我发现 95% 的内存问题来自于Bitmap类的错误使用。

于 2012-04-30T19:51:53.403 回答
-1

android开发者网站上有一篇关于位图使用的非常详细的文章。你看了吗?它解释了如何有效地加载、缓存和显示位图以及如何摆脱这个著名的 OutofMemoryError。

还有一个来自图像库的示例应用程序。我想这就是你要找的。

于 2012-04-30T20:08:56.860 回答