【问题标题】:Image management: When to recycle bitmaps?图像管理:何时回收位图?
【发布时间】:2013-10-23 04:29:50
【问题描述】:

我在这里阅读了When should I recycle a bitmap using LRU Cache 和其他几个问题,但仍在为 OutOfMemoryExceptions 苦苦挣扎。但我已经超前了。

我正在接管一个显示大量图像的应用。这主要是在网格视图中使用子类 ArrayAdapter 完成的。使用异步任务从 Web 加载图像,并存储在缓存中(我最终将切换到 LRU 缓存)。

网格视图中的每张图片都可以通向图像的详细视图(带有更多细节/UI 组件),这可以通向另一个网格视图。最终,堆栈上的视图太多,以至于我们的内存不足。正在通过Application.onLowMemory() 函数完全刷新缓存中的图像,但尽管如此,我们的内存已用完。

适配器在回收视图时从不检查缓存中是否有任何内容,我相信这可以给我一点喘息的空间,但感觉最大的收获是回收活动中的图像是堆栈中的 4 层以上。问题是,我不确定如何做到这一点。在onPause 例程中?

似乎当onPause 例程运行时(切换到下一个活动层),它显示的图像仍将在缓存中,因此它们不会被回收。我是否需要拉起 Activity 堆栈并在那时对旧的 Activity 调用一些自定义例程来告诉它们回收图像?

此外,我正在尝试支持 API 级别 9-19。 LRU 缓存是通过较低 API 的支持库提供的,API 12 中添加了全功能缓存,但显然如果我使用支持版本,任何运行 API 12+ 的设备都不会使用更新版本 - 我应该编写自定义代码来检测 API 版本,然后使用某种 LRUCache 工厂来创建我需要的版本?我是否需要编写自定义代码才能仅对低于 11 的 API 进行位图回收?

【问题讨论】:

    标签: android bitmap android-lru-cache


    【解决方案1】:

    我最终采用的解决方案是:

    我添加了支持 LRU Cache,然后还添加了 Jake Wharton 的 DiskLRU Cache。在从网上下载图像之前,我首先检查了内存 LRUCache,然后是 DiskLRUCache。下载的任何图像都存储在两者中。接下来,拥有任何图像的每个 Fragment 和 Activity 都注册为 LRU 缓存的侦听器。如果 LRU 缓存要驱逐一个图像为另一个图像腾出空间,它会向所有正在侦听的片段和活动发送通知。然后这些听众将他们的图像标记为“脏”,这意味着他们需要重新下载,然后在位图上调用recycle()。 这种方法总体上看起来效果很好。该应用程序仍然可能陷入垃圾收集的困境,并且最终在很长一段时间后仍然可能在旧手机上耗尽内存,但很难看出我可以在哪里进一步改进它。

    【讨论】:

      猜你喜欢
      • 2012-08-09
      • 2012-07-10
      • 1970-01-01
      • 1970-01-01
      • 2011-12-22
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多