【问题标题】:Error removing Bitmaps[Android]删除位图时出错[Android]
【发布时间】:2010-11-23 19:16:38
【问题描述】:

我正在开发一个在屏幕上绘制小位图的简单应用程序,但在清除屏幕时遇到了一点麻烦。我的位图存储在一个名为 _graphics 的 ArrayList 中,我需要清屏,所以我清空了我的 ArrayList。这在清除屏幕时效果很好,但是过了一会儿我的应用程序强制关闭了。

如果我在屏幕上绘制大约 50 个位图,它会在我第一次清除它时强制关闭,但是如果我只绘制 5 个,我可以在它崩溃之前获得大约 10 个清除。我认为这与 GC 未正确清除位图有关。有人对这个主题有想法吗?

【问题讨论】:

标签: java android bitmap


【解决方案1】:

查看 Logcat 文件我似乎发现了错误(新的 Android 开发人员:p 甚至不知道它存在)。这是由于 ConcurrentModificationException。现在一切似乎都在工作=D

【讨论】:

    【解决方案2】:

    好的 - 现在附加了堆栈跟踪:ConcurrentModificationException 您可以从不同的线程修改 ArrayList 或对其进行迭代。要么你必须同步访问,要么使用另一个集合,比如 ConcurrentHashSet。

    但也许以下(我的原始答案)也会很有趣:p

    听起来,您正在使用整个像素数据缓存真正的位图对象 -> 我猜,您遇到了 OutOfMemoryException

    垃圾收集器是异步操作,如果您清除位图数组,位图不会立即从内存中卸载。如果您要插入新的,则可能会发生旧的仍在内存中,而新的也会被加载。

    解决方案:不要以这种方式缓存位图,您正在这样做。

    它们是不同的东西,你可以尝试(取决于你的具体场景):

    1) 如果它们存储在 SD 卡或其他东西上,则仅缓存您收藏中位图的路径并加载它们(如果需要用于绘图)。

    2) 使用可绘制对象而不是位图——它们有一些有趣的方法和算法来优化对位图数据的访问。

    3) 要优化性能,请使用 SoftReference 或类似的东西 - 也许是 WeakRefernce。 SoftReferences 可以由 GC 按需卸载(当内存不足时)。在这种情况下,您必须检查软引用是否为空或仍然存在。 例如:

    ArrayList<SoftReference<Bitmap>> _graphics = new ArrayList<SoftReference<Bitmap>>();
    ...
    
    for (int i = 0; i < _graphics.size(); i++)
    {
        Bitmap b = _graphics.get(i).get();
        if (b == null)
        {
            b = loadFromSomewhere(i);
            _graphics.add(new SoftReference<Bitmap>(b), i);
        }
        ... do something wwith your bitmap
    }
    

    此代码片段未经 Java 编辑器测试或编写(请原谅输入错误或错误的方法签名)。

    【讨论】:

    • 2) 使用可绘制对象而不是位图——它们有一些有趣的方法和算法来优化对位图数据的访问。您能否详细说明这一点?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2012-05-13
    • 1970-01-01
    相关资源
    最近更新 更多