2013-01-24 32 views
0

在我的应用程序中,我有一个MapView自定义MapOverlays。Android并发修改错误MapOverlays

我已经覆盖了onDraw方法,所以我将能够聚集覆盖物品在相同的位置 - 它很好。

现在我想补充一大束的标记,我也得到一个Concurrent Modification Error虽然我有同步的方法和正确的对象..

我认为这是与该方法的onDraw是每次需要时都会调用多次(这可以在某些线程中读取) - 并且它必须在更新ArrayList的同时尝试迭代它。

我的问题是,为什么我没有同步,它...它应该被锁定..

我的功能是从的onDraw()调用:?

private synchronized ArrayList<OverlayItem> createOverlayItems(MapView mapView) 
    { 
     Projection projection = mapView.getProjection(); 
     int minPixelDistance = app.getPixels(50); //distance allowed between 2 markers  
     synchronized (fullMapOverlays) { 
      OverlayItem me = getOverlayItem(ME); 
      fullMapOverlays.remove(me); 
      mapOverlays.clear(); 
      mapOverlays.addAll(fullMapOverlays); 
      Iterator<OverlayItem> overlayIterator = fullMapOverlays.iterator(); 
      while (overlayIterator.hasNext()) 
      { 
       OverlayItem item = overlayIterator.next(); 
       Point currentItemPoint = projection.toPixels(item.getPoint(), null); 
       if (!isPointInScreen(currentItemPoint)) 
        continue; 
       else if (item.getTitle().equals(ME) && item.getSnippet().equals(ME)) 
        continue; 
       else if (!mapOverlays.contains(item)) 
        continue; 

       cluster.clear(); 
       Iterator<OverlayItem> innerIterator = mapOverlays.iterator(); 
       while (innerIterator.hasNext()) 
       { 
        OverlayItem itemToCheck = innerIterator.next(); 
        Point checkingItemPoint = projection.toPixels(itemToCheck.getPoint(), null); 
        if (!isPointInScreen(checkingItemPoint)) 
        { 
         innerIterator.remove(); 
         continue; 
        } 
        else if (itemToCheck.getTitle().equals(ME) && itemToCheck.getSnippet().equals(ME)) 
         continue; 
        else if (itemToCheck.getTitle().equals(CLUSTER)) 
         continue;    

        if (!item.equals(itemToCheck)) 
        { 
         if (getPixelsDistance(currentItemPoint, checkingItemPoint) <= minPixelDistance) 
         { 
          cluster.add(itemToCheck); 
          innerIterator.remove(); 
         } 
        } 
       }   
       if (cluster.size() > 0) 
       { 
        mapOverlays.remove(item); 
        cluster.add(item);    
        String itemsTitle = ""; 
        for (int i=0; i<cluster.size(); i++) 
        { 
         if (i == 0) 
          itemsTitle += cluster.get(i).getTitle(); 
         else 
          itemsTitle += "|" + cluster.get(i).getTitle(); 
        } 
        OverlayItem clusterItem = new OverlayItem(cluster.get(0).getPoint(), CLUSTER, itemsTitle); 
        clusterItem.setMarker(boundCenterBottom(createClusterDrawable(cluster.size()))); 
        mapOverlays.add(clusterItem);    
       } 
      }  
      fullMapOverlays.add(fullMapOverlays.size(), me); 
      mapOverlays.add(mapOverlays.size(), me);    
     } 
     return mapOverlays; 
    } 

可爱的logcat:

01-25 00:27:47.070: W/System.err(4676): java.util.ConcurrentModificationException 
01-25 00:27:47.070: W/System.err(4676):  at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:576) 
01-25 00:27:47.070: W/System.err(4676):  at com.WhosAround.Activities.Map.MapOverlay.createOverlayItems(MapOverlay.java:169) 
01-25 00:27:47.070: W/System.err(4676):  at com.WhosAround.Activities.Map.MapOverlay.draw(MapOverlay.java:61) 
01-25 00:27:47.070: W/System.err(4676):  at com.google.android.maps.Overlay.draw(Overlay.java:179) 
01-25 00:27:47.075: W/System.err(4676):  at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42) 
01-25 00:27:47.075: W/System.err(4676):  at com.google.android.maps.MapView.onDraw(MapView.java:530) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.View.draw(View.java:6933) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.View.draw(View.java:6936) 
01-25 00:27:47.075: W/System.err(4676):  at android.widget.FrameLayout.draw(FrameLayout.java:357) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.View.draw(View.java:6936) 
01-25 00:27:47.075: W/System.err(4676):  at android.widget.FrameLayout.draw(FrameLayout.java:357) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.View.draw(View.java:6936) 
01-25 00:27:47.075: W/System.err(4676):  at android.widget.FrameLayout.draw(FrameLayout.java:357) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.View.draw(View.java:6936) 
01-25 00:27:47.075: W/System.err(4676):  at android.widget.FrameLayout.draw(FrameLayout.java:357) 
01-25 00:27:47.075: W/System.err(4676):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1917) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewRoot.draw(ViewRoot.java:1530) 
01-25 00:27:47.075: W/System.err(4676):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1266) 
01-25 00:27:47.080: W/System.err(4676):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1868) 
01-25 00:27:47.080: W/System.err(4676):  at android.os.Handler.dispatchMessage(Handler.java:99) 
01-25 00:27:47.080: W/System.err(4676):  at android.os.Looper.loop(Looper.java:130) 
01-25 00:27:47.080: W/System.err(4676):  at android.app.ActivityThread.main(ActivityThread.java:3691) 
01-25 00:27:47.080: W/System.err(4676):  at java.lang.reflect.Method.invokeNative(Native Method) 
01-25 00:27:47.080: W/System.err(4676):  at java.lang.reflect.Method.invoke(Method.java:507) 
01-25 00:27:47.080: W/System.err(4676):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907) 
01-25 00:27:47.080: W/System.err(4676):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665) 
01-25 00:27:47.080: W/System.err(4676):  at dalvik.system.NativeStart.main(Native Method) 

回答

1

确定发现了它,我更新从另一个线程的MapActivity ....

你必须确保你从UI线程加入OverlayItems。

0

mapOverlays.remove(item);看起来像是我的罪魁祸首。如果在迭代列表时直接删除项目,则会导致并发修改。

使用你的迭代器去除东西,而不是直接做。

+0

迭代器完成后实际发生的事情.. –