BitmapFun示例存在缓存问题

3

我正在使用Android的BitmapFun示例代码来管理应用程序中的位图。在ViewPager中,我一直遇到图像错乱或重复的问题。我已经追踪到以下代码是导致问题的原因:

ImageCache.java:

           /**
             * Notify the removed entry that is no longer being cached
             */
            @Override
            protected void entryRemoved(boolean evicted, String key,
                    BitmapDrawable oldValue, BitmapDrawable newValue) {
                if (RecyclingBitmapDrawable.class.isInstance(oldValue)) {
                    // The removed entry is a recycling drawable, so notify it 
                    // that it has been removed from the memory cache
                    ((RecyclingBitmapDrawable) oldValue).setIsCached(false);
                } else {
                    // The removed entry is a standard BitmapDrawable

                    if (Utils.hasHoneycomb()) {
                        // We're running on Honeycomb or later, so add the bitmap
                        // to a SoftRefrence set for possible use with inBitmap later
                        mReusableBitmaps.add(new SoftReference<Bitmap>(oldValue.getBitmap()));
                    }
                }
            }

当位图从缓存中移除时,它将被添加到可重复使用的位图列表中。在这种情况下,该位图仍然被ViewPager视图使用。当稍后创建另一个视图时(该位图仍在使用中),该位图将被重用并出现在ViewPager中的两个位置。
从LruCache中移除的位图并不一定可供重用。我已禁用了此代码中的位图重用,并且不再遇到问题。低分辨率图像不会出现此问题,因为位图在ViewPager的屏幕外限制范围内时不会从缓存中移除。我没有60 DPI图像的问题,但在160 DPI情况下经常遇到此问题。我认为在使用更高分辨率图像的原始BitmapFun示例中也会出现此问题。
还有其他人遇到过此问题吗?或者是我没有正确理解问题?
Kevin
1个回答

1
我认为代码的问题在于这一行。
mReusableBitmaps.add(new SoftReference<Bitmap>(oldValue.getBitmap()));

这行代码将从LRU缓存中删除的位图添加到可重用的位图集中,以供inBitmap重复使用。它没有检查它是否仍然被ImageView使用。如果尝试重复使用仍在ImageView中使用的位图,则底层位图将被另一个位图替换,使其无效。我的建议是,在将位图添加到可重用的位图集之前,跟踪位图是否仍在ImageView中使用。我为此问题创建了一个示例github 项目。请告诉我您对我的解决方案的看法。


谢谢,看起来你的解决方案应该是可行的。我通过不在可重用位图集中设置位图来解决了这个问题,这可能会导致一些性能损失,但至少它可以工作。 - Kevin Beck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接