Android 2.1 GoogleMaps ItemizedOverlay ConcurrentModificationException

发布于 2024-09-02 04:48:24 字数 3464 浏览 9 评论 0原文

我无法弄清楚 ConcurrentModificationException 的来源。在我的 activity 中,我正在调用 updateMapOverlay()。我还在定期调用的另一个线程(TimerTask)内调用 updateMapOverlay()。从两个线程调用 updateMapOverlay() 时,我会采取适当的锁定。导致此问题的原因是我从非 UI 线程(即 TimerTask)内部调用 updateMapOverlay 吗?还有其他人遇到过类似的问题吗?

<代码> 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

I cannot figure out the origin of the ConcurrentModificationException. In my activity I'm calling
updateMapOverlay(). I'm also calling updateMapOverlay() inside another Thread (a TimerTask) that is invoked on regular intervals. I'm taking the appropriate locks when invoking updateMapOverlay() from both the threads. Is this problem being caused because I'm invoking updateMapOverlay from inside a non-UI thread (i.e., TimerTask). Has anyone else faced a similar issue ?


private void updateMapOverlay() {

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

}

Thanks.

Exception:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

聆听风音 2024-09-09 04:48:24

这个问题是因为
我正在调用 updateMapOverlay
在非 UI 线程内

是的。

我还调用 updateMapOverlay()
在另一个线程(TimerTask)内
定期调用。

为什么要不断删除和添加覆盖层?只需更新覆盖并使其失效即可。请参阅此处了解异步更新叠加层的示例

Is this problem being caused because
I'm invoking updateMapOverlay from
inside a non-UI thread

Yes.

I'm also calling updateMapOverlay()
inside another Thread (a TimerTask)
that is invoked on regular intervals.

Why are you removing and adding an overlay constantly? Just update the overlay and invalidate. See here for an example of updating an overlay asynchronously.

泪意 2024-09-09 04:48:24

感谢您的回复。

但是,在您的代码中,您不是在执行类似的操作 (map.getOverlays().remove(sites);map.getOverlays().add(sites); )?

<代码>
类 OverlayTask 扩展 AsyncTask {
@覆盖
公共无效onPreExecute(){
if (站点!=null) {
map.getOverlays().remove(sites);
地图.invalidate();
站点=空;
}
}

 @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();
 }
}

Thank you for your response.

However, in your code aren't you doing something similar (map.getOverlays().remove(sites); and map.getOverlays().add(sites);)?


class OverlayTask extends AsyncTask {
@Override
public void onPreExecute() {
if (sites!=null) {
map.getOverlays().remove(sites);
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();
 }
}
迷鸟归林 2024-09-09 04:48:24

一般来说,只要您只在 UI 线程上修改 ItemizedOverlay 的支持列表/地图,您就应该是安全的。

正如 Mark 指出的,AsyncTask 的:

@Override
protected void onPostExecute(Cursor cursor) {

    // modify List/Map

    populate();
    mapView.invalidate();
}

始终在 UI 线程上执行,因此此处的修改是安全的。

Generally speaking you should be safe as long as you only modify your ItemizedOverlay's backing List/Map on the UI thread.

As Mark pointed out, AsyncTask's:

@Override
protected void onPostExecute(Cursor cursor) {

    // modify List/Map

    populate();
    mapView.invalidate();
}

is always executed on the UI thread, so modifications are safe here.

稀香 2024-09-09 04:48:24

我也有同样的问题。为了回答您关于“为什么要不断删除和添加覆盖层?”的问题,我这样做是因为我的一些覆盖层项目可能不再存在,或者可能会出现新的覆盖层项目,而现有的覆盖层项目可能会改变位置,具体取决于我的特定应用程序的其余部分发生了什么。另外,我发现无法在不扩展 OverlayItem 的情况下更改其位置,以便我可以这样做。

此外,更改逐项覆盖中的项目是否也会导致并发修改异常?

I'm having the same problem. To answer your question as to "why are you removing and adding an overlay constantly?", I'm doing it because some of my overlay items might no longer exist, or new ones might appear, and existing ones may change location, depending on what's happening in the rest of my particular application. Also, I've found no way of changing the location of an OverlayItem without extending it so that I can do so.

Besides, wouldn't changing what items are in the itemized overlay also cause a concurrent modification exception?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文