我的应用程序中的几个ActivityListView中显示图像,其中ListView的每一行都包含一个ImageView

这样的示例是搜索屏幕,用户可以在其中搜索,获取结果,并显示每个结果的图片。

我试图权衡实现全局LruCache与使每个Activity包含其自己的本地LruCache的成本/收益。

这是我的两个主要问题。两者都围绕着我的应用程序很大这一事实,这意味着有很多屏幕可以显示这些图像。另外,我的应用程序具有流行的侧边菜单导航方式。因此,我可以打开菜单,点击Activity B,打开菜单,点击Activity A,打开菜单...等等,然后无限期地创建ABCCABABABABABAB的Activity堆栈。

全球

使用来自全局ActivityImageViewBitmapLruCache是否不包含对这些Bitmaps的引用?假设用户通过单击某些Activity来离开此Button。该Activity现在位于Activity堆栈上,并且仍保留对这些Bitmaps的引用。如果LruCache弹出Bitmap,当堆栈中某些Bitmap中的ImageView引用了它时,真的可以收回该Activity吗?

我以前创建了自己的自定义缓存。如果我在recycle()上调用Bitmap,然后用户单击“后退”按钮返回到包含设置为该ActivityImageView的堆栈中的某些Bitmap,则该应用程序将崩溃。这就是为什么我认为堆栈上ImageView上的Activity仍然保留对Bitmap的引用。

本地

如前所述。我的应用程序很大,导航的侧菜单样式允许用户创建相当大的Activity堆栈。这会创建很多LruCache。而且,由于初始化时必须声明LruCache的大小,因此似乎没有任何好的选择大小的方法。

有什么想法吗?有什么建议吗?

在这一点上,我认为我必须进行全局操作,但是我不知道如何解决Activity堆栈引用问题。我无法想象这不是很多应用程序都没有遇到的问题。我不知道为什么我找不到有关它的信息。

最佳答案

我正在尝试权衡实施全球战略的成本/收益
  LruCache与让每个Activity包含其自己的本地LruCache。


全局LruCache是​​前进的方式,因为在不同的活动实例中可能会引用同一组位图。可以将LruCache定义为Application的一部分。如果活动堆栈可以承载同一活动的多个实例(例如ABABABAB ..),那么在该活动中本地创建LruCache将是一个坏主意。很快就会出现内存不足的情况,因为每个活动实例中的LruCache都会在Dalvik VM中保留定义的内存量。假设应用程序内存为32Mb,并且您将LruCache大小确定为4Mb,即1/8。现在,当我们创建活动A的近7个实例时,内存消耗将达到7 * 4 = 28Mb,这本身可能会触发OOM。


  不会使用来自全局LruCache的位图使用ImageViews进行活动
  包含对这些位图的引用?


是的,ImageView也将对位图有很强的引用。如果引用在LruCache中维护,则此时引用计数将为2。


  如果LruCache弹出一个位图,则该位图是否真的可以回收?
  当堆栈中某个Activity中的ImageView拥有对
  它?


没有位图内存无法回收,因为仍有一些ImageView对其有很强的引用。


  在这一点上,我认为我必须进行全球化,但是我不知道该怎么做。
  解决活动堆栈参考问题。


LruCache的主要作用是保持对频繁使用的位图的强大引用。这样,如果任何ImageView都没有强引用,则可以防止位图被垃圾回收。

还要记住,对于Android 2.3.3及更低版本,您需要实现引用计数机制,以回收位图。

08-18 04:32