在SurfaceView上绘图时出现ConcurrentModificationException?

时间:2012-05-01 13:45:41

标签: android

假设我有一个“blob”对象的ArrayList,我循环并然后绘制到画布上。

     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 个答案:

答案 0 :(得分:3)

似乎您在迭代该列表时向列表中添加了一个新blob。一个简单的解决方法是在循环之前制作列表的副本。如果您在迭代时添加项目,则不会将其考虑在内。

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

答案 1 :(得分:3)

您可以将CopyOnWriteArrayList用于Blob

答案 2 :(得分:1)

您需要在onTouchListener中使用第二个列表myBlobList2:

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

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

如果出现以下情况,仍会出现同步问题:

  • 在myBlobList.addAll
  • 期间将对象添加到myBlobList2

答案 3 :(得分:1)

您可以使用simple 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循环在迭代ArrayList时保持Iterator。