2012-12-14 67 views
0

我有一个Android Google Maps应用程序,我正在通过Eclipse进行调试。我得到这个错误:如何诊断Android ConcurrentModificationException

12-14 16:19:50.106: E/AndroidRuntime(2487): FATAL EXCEPTION: main 
12-14 16:19:50.106: E/AndroidRuntime(2487): java.util.ConcurrentModificationException 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:41) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at com.google.android.maps.MapView.onDraw(MapView.java:494) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.View.draw(View.java:6740) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewGroup.drawChild(ViewGroup.java:1640) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewGroup.drawChild(ViewGroup.java:1638) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.View.draw(View.java:6743) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.widget.FrameLayout.draw(FrameLayout.java:352) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewGroup.drawChild(ViewGroup.java:1640) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewGroup.drawChild(ViewGroup.java:1638) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.View.draw(View.java:6743) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.widget.FrameLayout.draw(FrameLayout.java:352) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1842) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewRoot.draw(ViewRoot.java:1407) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1163) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1727) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.os.Handler.dispatchMessage(Handler.java:99) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.os.Looper.loop(Looper.java:123) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at java.lang.reflect.Method.invokeNative(Native Method) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at java.lang.reflect.Method.invoke(Method.java:521) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
12-14 16:19:50.106: E/AndroidRuntime(2487):  at dalvik.system.NativeStart.main(Native Method) 

我从来没有明确地使用迭代器(我的代码现在没有,但显然有些调用包括一个),而且我确信,任何类型的列表只能通过访问什么从Collections.synchronizedList返回,这应该解决了这个问题,以我的有限理解。因为我不知道在我的代码库中会产生什么,所以我不能真正发布代码片段。有谁知道其他“正常”原因?或者如何从logcat打印输出中得到任何有意义的位置(据我所知,唯一的文件引用是库文件)?

+1

“我从不显式使用迭代器” - 您会注意到它是具有迭代器的MapView的'onDraw()'。 “因为我似乎无法从LogCat中复制和粘贴” - 在Eclipse中,突出显示LogCat中的行并按下Ctrl-C。 – CommonsWare

+4

Collections.synchronizedList实际上并没有解决这个问题。如果在使用迭代器(包括增强型for-loop)时列表发生更改,则会发生异常。同步各个方法调用不会停止在迭代器调用之间更改列表。 – Affe

+0

我看到它是MapView的onDraw,但是那不是我写的代码,所以我假设它是自动生成的或者库代码?我可能会这样做会导致我没有写的代码出现问题? – akroy

回答

2

I'm assuming it's autogenerated or library code?

这是库代码。

What might I be doing that would cause a problem for code I didn't write?

要修改在正在遍历在主应用程序线程,例如通过添加或删除在后台线程中的覆盖在后台线程的集合。

不幸的是,Android版Google地图API的经典版本和V2版本都不是开放源代码,因此很难从堆栈跟踪中准确判断发生了什么。我的猜测是你在后台线程中添加或删除覆盖。

+0

哦,这是有道理的。是的,我在回调函数中添加/删除叠加层。我在覆盖图中有很多点,所以当视图窗口改变时,我删除旧的覆盖图,并生成新的覆盖点。是否需要通过适当的方式手动逐步添加叠加层并删除每个点,以便重新使用叠加层? – akroy

+0

@Akroy:“是否有正确的方法去手动遍历覆盖并删除每个点,以便我可以重用覆盖? - 如果这是一个'ItemizedOverlay',当准备好替换最后一次'populate()'调用提供的内容时,正确的方法是在'ItemizedOverlay'上调用'populate()'。您将要在主应用程序线程AFAIK上调用'populate()'。 – CommonsWare

+0

原谅一个新手;我正在阅读有关填充,但我仍然不清楚。是否填充基本上转储之前在ItemizedOverlay中的所有内容,留下一个空的Overlay以重用? – akroy