1

我找不出ConcurrentModificationException的来源。在我的activity中,我打电话给 updateMapOverlay()。我还在另一个线程(TimerTask)内调用updateMapOverlay(),该线程会定期调用。从两个线程调用updateMapOverlay()时,我正在采取适当的锁。这个问题是由于我从非UI线程(即TimerTask)中调用updateMapOverlay而引起的。有没有其他人面临类似的问题?Android 2.1 GoogleMaps ItemizedOverlay ConcurrentModificationException

private void updateMapOverlay() {

this.itemizedOverlay.refreshItems(createOverlayItemsList()); 
    List<Overlay> overlays = mapView.getOverlays(); 
    overlays.clear(); 
    overlays.add(cotItemizedOverlay); 
      this.mapview.invalidate(); 

} 

感谢。

异常

W/dalvikvm(10641): threadid=3: thread exiting with uncaught exception (group=0x4001b180) 
E/AndroidRuntime(10641): Uncaught handler: thread main exiting due to uncaught exception 
E/AndroidRuntime(10641): java.util.ConcurrentModificationException 
E/AndroidRuntime(10641): at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:64) 
E/AndroidRuntime(10641): at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:41) 
E/AndroidRuntime(10641): at com.google.android.maps.MapView.onDraw(MapView.java:494) 
E/AndroidRuntime(10641): at android.view.View.draw(View.java:6535) 
E/AndroidRuntime(10641): at android.view.ViewGroup.drawChild(ViewGroup.java:1531) 
E/AndroidRuntime(10641): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
E/AndroidRuntime(10641): at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 
E/AndroidRuntime(10641): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
E/AndroidRuntime(10641): at android.view.View.draw(View.java:6538) 
E/AndroidRuntime(10641): at android.widget.FrameLayout.draw(FrameLayout.java:352) 
E/AndroidRuntime(10641): at android.view.ViewGroup.drawChild(ViewGroup.java:1531) 
E/AndroidRuntime(10641): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
E/AndroidRuntime(10641): at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 
E/AndroidRuntime(10641): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
E/AndroidRuntime(10641): at android.view.View.draw(View.java:6538) 
E/AndroidRuntime(10641): at android.widget.FrameLayout.draw(FrameLayout.java:352) 
E/AndroidRuntime(10641): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1830) 
E/AndroidRuntime(10641): at android.view.ViewRoot.draw(ViewRoot.java:1349) 
E/AndroidRuntime(10641): at android.view.ViewRoot.performTraversals(ViewRoot.java:1114) 
E/AndroidRuntime(10641): at android.view.ViewRoot.handleMessage(ViewRoot.java:1633) 
E/AndroidRuntime(10641): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime(10641): at android.os.Looper.loop(Looper.java:123) 
E/AndroidRuntime(10641): at android.app.ActivityThread.main(ActivityThread.java:4363) 
E/AndroidRuntime(10641): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime(10641): at java.lang.reflect.Method.invoke(Method.java:521) 
E/AndroidRuntime(10641): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
E/AndroidRuntime(10641): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
E/AndroidRuntime(10641): at dalvik.system.NativeStart.main(Native Method) 
I/Process ( 95): Sending signal. PID: 10641 SIG: 3 

回答

5

是因为 我从 调用updateMapOverlay非UI线程

是内部引起此问题。

我还呼吁updateMapOverlay() 另一个线程(一个TimerTask) 是在定期调用里面。

为什么要不断移除和添加覆盖层?只需更新覆盖并使其无效。请参阅here for an example异步更新覆盖。

1

谢谢你的回应。

但是,在你的代码中,你是不是在做类似的事情(map.getOverlays().remove(sites);map.getOverlays().add(sites);)?

类OverlayTask扩展的AsyncTask { @覆盖 公共无效onPreExecute(){ 如果(网站!= NULL){ map.getOverlays()删除(点)。 map.invalidate(); sites = null; }}

@Override 
public Void doInBackground(Void... unused) { 
    SystemClock.sleep(5000); // simulated work 

sites=new SitesOverlay(); 

return(null); 

}

@Override 
public void onPostExecute(Void unused) { 
    map.getOverlays().add(sites); 
    map.invalidate(); 
} 
} 
+0

你是对的 - 只需将清理移动到在UI线程上运行的onPreExecute。 – 2011-12-02 17:18:43

0

我有同样的问题。要回答你的问题:“你为什么要不断删除和添加叠加层?”,我这样做是因为我的一些叠加项可能不再存在,或者新的可能会出现,现有的可能会改变位置,具体取决于在我的特殊应用程序的其余部分发生了什么。此外,我发现没有办法改变OverlayItem的位置而不扩展它,以便我可以这样做。

此外,不会更改条目叠加中的哪些项目也会导致并发修改异常?

1

一般而言,只要您仅在UI线程上修改了您的ItemizedOverlay的支持List/Map,您应该是安全的。

正如马克指出,的AsyncTask的:

@Override 
protected void onPostExecute(Cursor cursor) { 

    // modify List/Map 

    populate(); 
    mapView.invalidate(); 
} 

在UI线程上总是执行,这样的修改是安全的在这里。

+0

找到关于这个主题的好文章,其中提出了几种不同的方法:http://developer.android.com/resources/articles/painless-threading.html – 2010-12-28 13:38:26