4

我已经做了以下事情来处理我在应用程序中的位图:

  1. LruCache对于Bitmaps大小为 1/8 的内存
  2. BitmapFactory.Options用于计算inSampleSize
  3. OOM在创建Bitmaps,调用evictAllSystem.gc()那里时捕获
  4. 有时也有AsyncTask解码Bitmaps

我使用BitmapFactory.decodeFile它,看起来 VMBitmaps从内存中释放的速度不够快。我在某处读到可能存在错误,BitmapFactory.decodeFile所以我尝试使用BitmapFactory.decodeFileDescriptor,但我随机得到以下信息:

skia --- 解码器->解码返回 false

如果我不想使用或做其他事情,这里是否有问题FileInputStream需要修复。BitmapFactory.decodeFileDescriptor

这花了我太多时间,我已经阅读了所有基于此的解决方案以及谷歌建议如何Bitmap处理,我已经走到了死胡同。

谢谢。

4

3 回答 3

2

我最终在这里SoftRefences使用Bitmap。现在我可以看到 GCBitmaps在快速滚动时一直在释放我未使用的GridView东西。

测试设置我的LruCache大小全内存大小,仍然没有得到 OOM。

使用这种方法的惩罚不是那么明显,GridView考虑到它正在绘制非常自定义的图像,我的滚动非常顺利。

于 2013-09-17T12:57:07.677 回答
2

使用大位图总是有机会出现内存不足异常..所以要通过Android博客来处理

http://developer.android.com/training/displaying-bitmaps/index.html

并且总是回收 Bimap

ImageView mImage;
Drawable toRecycle = mImage.getDrawable();
        if ( toRecycle != null && toRecycle instanceof BitmapDrawable ) {
            if ( ( (BitmapDrawable) mImage.getDrawable() ).getBitmap() != null )
                ( (BitmapDrawable) mImage.getDrawable() ).getBitmap().recycle();
        }
于 2013-09-17T12:02:42.670 回答
0

System.gc() 不会帮助你,也不保证任何事情。

如果您绝对确定,不再需要被逐出的位图并且在任何地方都没有引用它们(否则将捕获“无法绘制回收的位图”异常)我建议您将 EvictionListener 添加到 LRU 缓存并调用位图。 recycle() 在每个被驱逐的值上。

不记得默认的 LRU 缓存是否提供了设置驱逐监听器的便捷方法,但如果没有,扩展它并添加所需的功能非常容易。

PS 我建议不要使用 Wea​​kReferences,因为您失去了对位图和 LRU 目的的任何控制。即使您加载 8 个位图,它们很好地适合您的 1/8 内存,但屏幕一次只能显示其中 4 个(ImageViews 对位图有很强的引用)gc 会尽快清除剩余的 4 个。我的意思是超快。您必须为正在显示的每个新行(在 ListView 的情况下)重新加载位图。并且每个离开屏幕的位图都必须重新加载。

于 2013-09-17T12:18:01.970 回答