2013-01-24 43 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

迭代器完成後實際發生的事情.. –