我正在开发一个简单的应用程序,它将小位图绘制到屏幕上,并且在清除屏幕时遇到一些麻烦。我的位图存储在一个名为_graphics的ArrayList中,我需要清除屏幕,所以我清除了我的ArrayList。这在清除屏幕时效果很好,但是一段时间后我的app力就会关闭。
如果我在屏幕上绘制大约50个位图,它会在我第一次清除它时强制关闭,但是如果我只绘制5,我可以在它崩溃之前获得大约10个清除。我认为这与GC没有正确清除位图有关。有没有人有关于这个问题的想法?
答案 0 :(得分:1)
浏览Logcat文件我似乎发现了错误(新Android Dev:p甚至不知道它存在)。这是由于ConcurrentModificationException。现在一切似乎都在起作用= D
答案 1 :(得分:1)
好的 - 现在附加了堆栈跟踪:ConcurrentModificationException 您可以从不同的线程修改ArrayList或迭代它。您必须同步访问权限或使用另一个集合,如ConcurrentHashSet。
但也许以下(我的起源答案)也会很有趣:p
听起来,您正在使用整个像素数据缓存真实的Bitmap对象 - >我想,你得到了OutOfMemoryException
垃圾收集器是一个异步操作,如果清除位图数组,位图不会立即从内存中卸载。如果要插入新的,可能会发生旧的仍在内存中,新的也会被加载。
解决方案:不要以这种方式缓存位图,而是这样做。
它们是不同的东西,你可以尝试(取决于具体的场景):
1)如果它们存储在SD卡或其他东西上,只需缓存集合中位图的路径并加载它们(如果需要绘图)。
2)使用Drawable对象而不是位图 - 他们有一些有趣的方法和算法来优化对位图数据的访问。
3)要优化性能,请使用SoftReference或类似内容 - 也许WeakRefernce。 GC可以根据需要卸载SoftReferences(当内存变低时)。在这种情况下,您必须检查软修复是否为空或仍然存在。 E.g:
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
}
此代码snipet未使用Java编辑器进行测试或编写(请原谅输入错误或错误的方法签名)。