删除位图时出错[Android]
我正在开发一个简单的应用程序,它将小位图绘制到屏幕上,并且在清除屏幕时遇到一些麻烦。我的位图存储在名为 _graphics 的 ArrayList 中,并且我需要清除屏幕,因此我清除了 ArrayList。这在清除屏幕方面效果很好,但是过了一会儿我的应用程序强制关闭。
如果我在屏幕上绘制大约 50 个位图,它会在我第一次清除它时强制关闭,但是如果我只绘制 5 个,我可以在崩溃之前获得大约 10 个清除。我认为这与 GC 未正确清除位图有关。有人对这个主题有想法吗?
I am working on a simple application that draws small bitmaps onto the screen, and have a little trouble clearing the screen. My bitmaps are stored in an ArrayList called _graphics, and I need to clear the screen, so I clear my ArrayList. This works fine in clearing the screen, however after a while my app force closes.
If I draw around 50 bitmaps on the screen, it will force close the first time I clear it, however if I only draw 5, I can get about 10 Clears before it crashes. I assume this is something to do with the GC not clearing the bitmaps correctly. Does anyone have an ideas on the subject?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查看 Logcat 文件我似乎发现了错误(New Android Dev :p 甚至不知道它存在)。这是由于 ConcurrentModificationException 引起的。现在一切似乎都正常=D
Going over the Logcat File I seem to have found the error (New Android Dev :p Didn't even know it existed). It was due to a ConcurrentModificationException. Everything seems to be working now =D
好的 - 现在附加了堆栈跟踪:ConcurrentModificationException
您可以从不同的线程修改 ArrayList 或对其进行迭代。您必须同步访问或使用其他集合(例如 ConcurrentHashSet)。
但也许以下(我的原始答案)也会很有趣:p
听起来,您正在使用整个像素数据缓存真正的位图对象 ->我猜,你得到了 OutOfMemoryException
垃圾收集器是一个异步操作,如果你清除位图数组,位图不会立即从内存中卸载。如果您要插入新的,则可能会发生旧的仍在内存中并且新的也会被加载的情况。
解决方案:不要以您正在做的方式缓存位图。
它们是不同的东西,您可以尝试(取决于您的具体场景):
1)如果它们存储在 SD 卡或其他东西上,则仅缓存集合中位图的路径并加载它们(如果需要绘制)。
2)使用Drawable对象而不是位图——它们有一些有趣的方法和算法来优化对位图数据的访问。
3)要优化性能,请使用类似 SoftReference 或类似 - 也许 弱引用。 SoftReferences 可以根据需要由 GC 卸载(当内存变低时)。在这种情况下,您必须检查软引用是否为空或仍然存在。
例如:
此代码片段未经 Java 编辑器测试或编写(请原谅输入错误或错误的方法签名)。
OK - now the stack trace is attached: ConcurrentModificationException
You modify the ArrayList from different threads or iterating over it. Either you have to synchronize the access or use another collection like ConcurrentHashSet.
But maybe the following (my origin answer) will be interesting too :p
Sounds like, that you are caching the real Bitmap objects with the whole pixel data -> I guess, you got OutOfMemoryException
The garbage collector is an asynchronous operation and if you clear your bitmap array, the bitmaps are not unloaded from memory instantly. If you are inserting new ones, it can happen, that the old are still in memory and the new ones gets loaded too.
Solution: Do not cache the bitmaps in that way, you are doing.
They are different things, you can try (depends on yout concrete scenrario):
1) If they are stored on SD card or something else, cache only the path to the bitmaps in your collection and load them, if they are needed for drawing.
2) Use Drawable objects instead of bitmaps - theys have some interesting methods and algorithm for optimized access to the bitmap data.
3) To optimize the performance use something like SoftReference or similar - maybe WeakRefernce. SoftReferences can be unloaded by the GC on demand (when memory gets low). In that case you have to check, whether the soft refence is null or still exists.
E.g:
This code snipet is not tested or written with an Java Editor (please excuse typing errors or wrong method signatures).