代码之家  ›  专栏  ›  技术社区  ›  Soumya Simanta

Android 2.1谷歌地图逐条列出了Doverlay ConcurrentModificationException

  •  1
  • Soumya Simanta  · 技术社区  · 14 年前

    我不知道 ConcurrentModificationException . 在我的 activity 我打电话来 updateMapOverlay() . 我也在打电话 updateMapOverlay() 在另一条线内(a TimerTask )定期调用。我在调用时使用了适当的锁 更新映射覆盖() 从两个线程。这个问题是不是因为我在调用 updateMapOverlay 从非UI线程(即, 定时器任务 )其他人也遇到过类似的问题吗?

    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
    
    4 回复  |  直到 12 年前
        1
  •  5
  •   CommonsWare    14 年前

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

    对。

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

    为什么要经常删除和添加覆盖?只需更新覆盖并使其失效。见 here for an example 异步更新覆盖。

        2
  •  1
  •   Soumya Simanta    14 年前

    谢谢你的回复。

    但是,在您的代码中,您不是在做类似的事情吗?( map.getOverlays().remove(sites); 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();
     }
    }
    
        3
  •  1
  •   Torben Vesterager    14 年前

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

    正如马克指出的,异步任务:

    @Override
    protected void onPostExecute(Cursor cursor) {
    
        // modify List/Map
    
        populate();
        mapView.invalidate();
    }
    

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

        4
  •  0
  •   Ogre    14 年前

    我也有同样的问题。回答你的问题“为什么你要不断地移除和添加覆盖层?”,我这样做是因为我的某些覆盖项可能不再存在,或者可能会出现新的覆盖项,并且现有的覆盖项可能会更改位置,这取决于我的特定应用程序的其余部分发生了什么。此外,我还发现,如果不扩展覆盖项,就无法更改它的位置,以便我可以这样做。

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