android: ConcurrentModificationException с наложениями карты

Я попытался найти это в других темах и применить найденные там решения к своей проблеме, но, похоже, ничего не помогло. Итак, вот оно:

В одном классе, который у меня есть, который создает новый полигональный оверлей:

 public void addPolyLines(ArrayList<KrollDict> polyLines){
    // Remove the line overlay
    List<Overlay> mMapOverlays = view.getOverlays();
    boolean rm = mMapOverlays.remove(polyLineOverlay);    

    polyLineOverlay = new PolygonOverlay(polyLines); // KEY LINE

    mMapOverlays.add(polyLineOverlay);
    view.invalidate();
}

И это внутренности моего класса PolygonOverlay. В строке while (it.hasNext ()) возникает исключение одновременной модификации, и я не могу понять, почему. Я не верю, что модифицирую массив mPolyLines. drawLines вызывается из собственного метода рисования Overlays, и иногда кажется, что он вызывается постоянно.

ArrayList<KrollDict> mPolyLines;

public PolygonOverlay(ArrayList<KrollDict> polyLines){
        mPolyLines = polyLines;
}

public void drawLines(MapView mv, Canvas canvas) {
        Iterator<KrollDict> it = mPolyLines.iterator();

        // Go through each line
        while(it.hasNext()){// CONCURRENTMODIFICATIONEXCEPTION THROWN HERE
            KrollDict kd = it.next();
            String[] pointsArr = kd.getStringArray("points");
            String color = kd.getString("color");
            float width = new Float(kd.getDouble("width")).floatValue(); 
            int alpha = kd.getInt("alpha");

            int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
            Paint paint = new Paint();
            paint.setColor(Color.parseColor(color));
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(width);
            //paint.setAlpha(alpha);

            // Loop through the coordinates
            for(int i = 0; i< pointsArr.length; i++){
                String[] coordinates = convertStringToArray(pointsArr[i]);
                Double latitude = new Double(Double.parseDouble(coordinates[3]) * 1E6);
                Double longitude = new Double(Double.parseDouble(coordinates[1]) * 1E6);
                GeoPoint gp = new GeoPoint(latitude.intValue(), longitude.intValue());                                      

                Point point = new Point();
                point = mv.getProjection().toPixels(gp, point);                 

                x2 = point.x;
                y2 = point.y;
                if (i > 0) {                        
                    canvas.drawLine(x1, y1, x2, y2, paint);
                }
                x1 = x2;
                y1 = y2;
            }
        }// while
    }

person Leonidas    schedule 23.01.2012    source источник
comment
см. этот поток stackoverflow .com / questions / 1775717 /   -  person aviad    schedule 23.01.2012
comment
Я не вижу ничего плохого в опубликованном вами коде. Дико догадываюсь, но, возможно, вы думаете, что оверлей повторяет свою собственную частную копию вашего ArrayList ‹KrollDict›, и что вы обновляете отдельную копию в другом месте (возможно, в другом потоке), тогда как на самом деле это один и тот же объект. Это возможно?   -  person Reuben Scratton    schedule 23.01.2012
comment
Это вполне возможно. Единственное другое место, которое я добавляю / удаляю из этого ArrayList, - это другой класс, который находится в другом потоке, но это происходит только тогда, когда пользователь нажимает кнопку добавления / удаления, после чего вызывается весь этот код. Как вы думаете, это могло быть так? Я предположил, что их звали один за другим ...   -  person Leonidas    schedule 23.01.2012


Ответы (1)


Пытаться

public PolygonOverlay(ArrayList<KrollDict> polyLines){  
    mPolyLines = (ArrayList<KrollDict>)polyLines.clone();  
}   

Создавая клон, вы должны быть защищены от того, чтобы кто-то изменил список, пока вы его просматриваете.

person Marc Van Daele    schedule 23.01.2012
comment
Или используйте конструктор копирования: mPolyLines = new ArrayList<KrollDict>(polyLines), сохраняет приведение. - person Matt; 23.01.2012