我想念Android中同步代码的概念。

场景

屏幕上始终绘制3个项目。每个图像都存储在ArrayList(lstGraphics)中。为此,我使用SurfaceView。用户点击图像后,图像获取的市场将被删除,而新的市场将被添加。

代码示例:

动画隐藏线程

...
    @Override
        public void run() {
            Canvas c;
            while (run) {
                c = null;
                try {
                    c = panel.getHolder().lockCanvas(null);
                      synchronized (panel.getHolder()) {

                        panel.updatePhysics();
                        panel.manageAnimations();
                        panel.onDraw(c);

                    }
                } finally {
                    if (c != null) {
                        panel.getHolder().unlockCanvasAndPost(c);
                    }
                }
            }
        }
...

如此看来,我首先是updatePhysics()。这意味着我要计算每个图像将移动到的方向。在这里,我还将从列表中删除单击的图像。之后,我检查是否需要在manageAnimations()的列表中添加新的Item,然后最后一步绘制整个内容。
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
....
 public void manageAnimations()
    {
          synchronized (this.getHolder()) {
            ...
        while (lstGraphics.size()<3) {
                lstGraphics.add(createRandomGraphic());
                }
        }
          }
    }

 @Override
    public boolean onTouchEvent(MotionEvent event) {
         synchronized (getHolder()) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                 //... check if a image has been clicked and then set its property
                        graphic.setTouched(true);

                 }
            }

            return true;
         }
    }

 public void updatePhysics() {
       synchronized (getHolder()) {

     for (Graphic graphic : lstGraphics) {
           //.... Do some checks
     if (graphic.isTouched())
      {
        lstGraphics.remove(graphic);
      }
     }
  }
 }

 @Override
    public void onDraw(Canvas canvas) {
         /// draw the backgrounds and each element from lstGraphics
}

public class Graphic {

        private Bitmap bitmap;
            private boolean touched;
            private Coordinates initialCoordinates;
....
}

我得到的错误是:
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): Uncaught handler: thread Thread-12 exiting due to uncaught exception
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): java.util.ConcurrentModificationException
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): at java.util.AbstractList$SimpleListIterator.next(AbstractList.java:66)
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): at com.test.customcontrols.Panel.updatePhysics(Panel.java:290)
> 03-01 10:01:53.365: ERROR/AndroidRuntime(454): at com.test.customcontrols.AnimationHideThread.run(AnimationHideThread.java:41)

任何帮助是极大的赞赏。谢谢你。

最佳答案

您的问题出在物理方法中,您可以在其中添加图形和列表

public void updatePhysics() {
    synchronized (getHolder()) {
        for (Graphic graphic : lstGraphics) {
        //.... Do some checks
        if (graphic.isTouched()) {
            lstGraphics.remove(graphic); //your problem
        }
    }
}
for(Graphic graphic : lstGraphics)lst.Graphics.remove(graphic);的组合会导致ConcurrentModificationException,因为您正在运行列表并同时尝试对其进行修改。

到目前为止,我知道两种解决方案:
  • 如果有可用的话,请使用Iterator(到目前为止,尚未为Android进行编码)。
    while (iter.hasNext) {
        if (physicsCondition) iter.remove();
    }
    
  • 使用第二个列表来存储要删除的元素,然后再删除它们
    List<GraphicsItem> toRemove = new ....
    for (Graphic graphic : lstGraphics) {
        if (physicsCondition) {
            toRemove.add(graphic);
        }
    }
    lstGraphics.removeAll(toRemove);
    
  • 09-27 01:42