2012-12-14 29 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