从内存中删除图像数据

时间:2012-04-30 19:37:26

标签: android

我必须相信有一种方法可以在不再需要时从内存中清除图像数据,但是尽管进行了详尽的搜索,我找不到解决方案。堆栈和谷歌Android开发人员列表都充满了关于OOM错误的问题,特别是“位图大小超过VM预算”,但我仍然没有看到明确的答案。

我知道设备上存在硬内存限制,我知道加载和显示或缓存大量图像数据是不现实的,但是应该放弃不再需要的数据。

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

  1. 允许用户细读远程服务器图像的图库。
  2. 该服务器上可能有任意数量的图像。
  3. 该应用程序一次显示1张图像,并允许用户通过按下按钮或滑动一次返回或转发1张图像。
  4. 任何时候最多可以渲染3张图像(因此用户可以在滑动时立即看到当前图像左侧或右侧的图像)。应丢弃所有其他图像数据。
  5. 使用URL.openStream和Drawable.createFromStream或BitmapFactory.decodeStream加载图像。流已正确关闭。
  6. 在获取图像之前,在服务器上
  7. 加载发生在AsyncTasks中。不再需要的任务(由于远离具有不完整任务的图像而被取消)。 AyncTask中的任何引用都是WeaklyReferenced。
  8. 当不再需要任何图像时,它会通过以下方式“清除”:
    • 的getBackground()。setCallback(空)
    • 监听器设置为空
    • setImageDrawable / Bitmap(null)
    • removeView
  9. 这个简单的构造考虑了我所知道的所有建议实践,在某些时候不可避免地会因OOM错误而崩溃。使用inSampleSize和inPreferredConfig中的BitmapFactory.Options将延迟不可避免的,但不是永远的,并且以图像质量为代价。在这个例子中,我使用了远程图像,但是存在于/ assets /或内部存储器等中的图像存在问题。

    我的感觉是,如果我们可以在一个点上显示X量的图像数据,并且我们采取所有步骤从内存中删除该图像数据,我们应该能够在以后显示相同数量的数据,而无需补偿对于之前发生的事情。

    关于这个问题的大量问题,我希望有一个标准的解决方案,但是如果有的话,我找不到它。我见过Romain Guy发布的答案,他对自己的知识非常慷慨,并且活跃于社区,他们说“简单。不要使用这么多记忆”。好。告诉我怎么做。

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

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

    TYIA。

    /这个问题也发布在Android开发人员谷歌群组列表中。

2 个答案:

答案 0 :(得分:3)

通过我与Prime的合作,我找到了一些提示,其中一个你没有提到过。解码位图时,请务必使用inPurgeable中的inInputShareableBitmapFactory.Options标记。这将有所帮助,但我建议你看看我在Prime中的图像加载实现。我在所有产品中使用它而没有任何内存问题。我发现95%的内存问题来自于Bitmap类的错误使用。

答案 1 :(得分:-1)

在android开发者网站上有一个非常detailed article关于位图的使用。 你看看了吗? 它解释了如何有效地加载,缓存和显示位图以及如何摆脱这个着名的OutofMemoryError。

图片库中还有a sample application。 我认为这就是你要找的东西。