ConcurrentModificationException при рисовании на SurfaceView?

1

Скажем, у меня есть ArrayList объектов "blob", которые я просматриваю и рисую на холсте.

     for (blob b:myBlobList)
     {
         canvas.drawCircle(b.X, b.Y, b.Size, paint);
     }

Также у меня есть onTouchListener, который добавляет новый объект blob всякий раз, когда поверхность коснется.

      if (event.getAction() == android.view.MotionEvent.ACTION_DOWN)
        {
          myBlobList.add(new blob());
          myBlobList.get(myBlobList.size()-1).X = event.getX();
          myBlobList.get(myBlobList.size()-1).Y = event.getY();;
        }

Однако вместе они вызывают ошибку ConcurrentModificationException. Каким будет ваше предложение, как мне это исправить?

Просто добавление

try{ ... } catch (ConcurrentModificationException e) {}

Делает мерцание экрана/холста, когда это исключение происходит, и это происходит очень часто. :)

Благодарю!

Теги:

4 ответа

2
Лучший ответ

Кажется, что вы добавляете новый blob в свой список, итерации по этому списку. Одним простым способом было бы сделать копию списка перед циклом. Если вы добавляете элементы во время итерации, они не будут приняты во внимание.

List<Blob> myBlobCopy = new ArrayList<Blob>(myBlobList); //copies the content
for (Blob b : myBlobCopy) {
    canvas.drawCircle(b.X, b.Y, b.Size, paint);
}
3

Вы можете использовать CopyOnWriteArrayList для своих Blobs

1

Вам понадобится второй список myBlobList2 для использования в onTouchListener:

for (blob b:myBlobList){
         canvas.drawCircle(b.X, b.Y, b.Size, paint);
     }

myBlobList.addAll(myBlobList2);
myBlobList2.clear();

Все еще проблемы синхронизации могут возникать, если:

  • добавить объект в myBlobList2 во время myBlobList.addAll
1

Вы можете использовать простой цикл for вместо цикла forEach и выполнять итерацию с помощью собственного счетчика индексов.

for(int i = 0; i < myBlobList.size(); i++){
   blob b = myBlobList.get(i);
   canvas.drawCircle(b.X, b.Y, b.Size, paint);
}

Это ConcurrentModificationException происходит из-за того, что вы добавляете или удаляете элемент из ArrayList из другого потока, в то время как цикл forEach удерживает Iterator при повторении через ArrayList.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню