实现全局LruCache与许多本地LruCache

时间:2014-09-02 17:07:58

标签: android imageview android-lru-cache

我的应用中的多个ActivityListView中显示图片,其中ListView的每一行都包含ImageView

这方面的一个例子是搜索屏幕,用户搜索,获取结果,并显示每个结果的图片。

我试图权衡实施全球LruCache与每个Activity包含其本地LruCache的成本/收益。

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

全球

使用Activity ImageView来自全球Bitmap的{​​{1}}个LruCache包含对这些Bitmaps的引用?假设用户点击某些Activity导航远离此ButtonActivity现在位于Activity堆栈上,仍然保留对Bitmaps的引用。如果LruCache弹出Bitmap,那么当堆栈中某些Bitmap中的ImageView拥有对它的引用时,Activity是否真的可以回收?< / p>

我之前创建了自己的自定义缓存。如果我在recycle()上调用了Bitmap,然后用户点击后退按钮返回到堆栈上的某个Activity,其中ImageView设置为Bitmap应用程序会崩溃。这就是为什么我认为堆栈上的ImageView上的Activity仍然保留对Bitmap s的引用。

本地

正如我前面提到的那样。我的应用程序非常庞大,侧面菜单导航样式允许用户创建相当大的Activity堆栈。这会产生很多LruCache个。而且,由于您在初始化时必须声明LruCache的大小,因此似乎没有任何好方法可以选择大小。

思考?建议?

此时我认为我必须做全局,但我不知道如何解决Activity堆栈引用问题。我无法想象这不是很多应用程序遇到的问题。我不知道为什么我没有找到有关它的信息。

1 个答案:

答案 0 :(得分:3)

  

我正在努力权衡实施全球化的成本/收益   LruCache与每个Activity包含自己的本地LruCache。

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

  

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

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

  

如果LruCache关闭了Bitmap,那么该Bitmap是否真的可以回收   当堆栈上某些Activity中的ImageView持有引用时   它?

不能回收位图内存,因为有些ImageView对它有强烈的引用。

  

此时我认为我必须做全球化,但我不知道如何做   解决Activity堆栈引用问题。

LruCache的主要作用是强烈引用更频繁使用的位图。因此,如果任何ImageView都没有强引用,则会阻止位图被垃圾回收。

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