在SurfaceView上绘制时出现ConcurrentModificationException?

3

假设我有一个“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个回答

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);
}

3
您可以使用CopyOnWriteArrayList来处理Blob。

1

你需要一个另外的名为myBlobList2的列表,然后在onTouchListener中使用它:

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

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

如果发生以下情况,仍可能出现同步问题:

  • 在 myBlobList.addAll 过程中向 myBlobList2 添加对象

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的出现是因为在forEach循环遍历ArrayList时,你从其他线程添加或删除元素,而此时迭代器仍在使用中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接