0

在我的应用程序中,我有一个带有自定义 MapOverlays 的 MapView。

我已经覆盖了 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)
4

2 回答 2

1

好的,找到了,我从另一个线程更新了 MapActivity....

您必须确保从 UI 线程添加 OverlayItems。

于 2013-01-25T09:01:25.680 回答
0

mapOverlays.remove(item); 看起来像我的罪魁祸首。如果您在迭代列表时直接删除一个项目,它将导致并发修改异常。

使用您的迭代器来删除事物,而不是直接进行。

于 2013-01-24T22:56:26.600 回答