Скажем, у меня есть 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) {}
Делает мерцание экрана/холста, когда это исключение происходит, и это происходит очень часто. :)
Благодарю!
Кажется, что вы добавляете новый blob в свой список, итерации по этому списку. Одним простым способом было бы сделать копию списка перед циклом. Если вы добавляете элементы во время итерации, они не будут приняты во внимание.
List<Blob> myBlobCopy = new ArrayList<Blob>(myBlobList); //copies the content
for (Blob b : myBlobCopy) {
canvas.drawCircle(b.X, b.Y, b.Size, paint);
}
Вы можете использовать CopyOnWriteArrayList
для своих Blobs
Вам понадобится второй список myBlobList2 для использования в onTouchListener:
for (blob b:myBlobList){
canvas.drawCircle(b.X, b.Y, b.Size, paint);
}
myBlobList.addAll(myBlobList2);
myBlobList2.clear();
Все еще проблемы синхронизации могут возникать, если:
Вы можете использовать простой цикл 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.