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

4 回答 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);
}
于 2012-05-01T13:50:19.080 回答
3

你可以使用CopyOnWriteArrayList你的 Blob

于 2012-05-01T14:00:09.637 回答
1

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

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

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

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

  • 在 myBlobList.addAll 期间将对象添加到 myBlobList2
于 2012-05-01T13:53:23.010 回答
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 循环在迭代 ArrayList 时持有 Iterator。

于 2012-05-01T14:05:38.767 回答