Android 动画中的 java.util.ConcurrentModificationException [英] java.util.ConcurrentModificationException in Android animation

查看:26
本文介绍了Android 动画中的 java.util.ConcurrentModificationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Android 中同步代码的概念有些怀念.

There is something I miss with the notion of Synchronizing code in Android.

场景

屏幕上总是绘制 3 个项目.每个图像都存储在一个 ArrayList (lstGraphics) 中.为此,我使用 SurfaceView.用户点击图片后,该图片的市场就会被移除,并会添加一个新的市场.

There are always 3 items drawn on the screen. Each image is stored in a ArrayList (lstGraphics). For this purpose I use a SurfaceView. Once the user taps on a image, the image get's market to be removed and a new one will be added.

代码示例:

动画隐藏线程

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

正如您首先看到的那样,我更新了Physics().这意味着我计算每个图像将移动到的方向.在这里,我还将从我的列表中删除点击的图像.之后,我检查是否需要在 manageAnimations() 的列表中添加一个新项目,然后最后一步绘制整个内容.

So as you can seem first I updatePhysics(). This means I calculate direction where each image will move to. In here I will also remove clicked images from my list. After that I check if I need to add a new Item in my list in manageAnimations() and then the final step draw the whole thing.

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)

非常感谢任何帮助.谢谢.

Any help is greatly appreciated. Thank you.

推荐答案

你的问题在于你的物理方法,你在那里添加了图形和列表

Your problem is in your physics method, where you add the graphic and the list

public void updatePhysics() {
    synchronized (getHolder()) {
        for (Graphic graphic : lstGraphics) {
        //.... Do some checks
        if (graphic.isTouched()) {
            lstGraphics.remove(graphic); //your problem
        }
    }
}

for(Graphic graphics : lstGraphics)lst.Graphics.remove(graphic); 的组合导致 ConcurrentModificationException 因为您正在运行您的列表并同时尝试修改它.

the combination of for(Graphic graphic : lstGraphics) and lst.Graphics.remove(graphic); causes the ConcurrentModificationException because you are running over your list and concurrently try to modify it.

目前我知道两种解决方案:

So far I know two solutions:

  1. 如果迭代器可用,请改用迭代器(迄今为止从未为 Android 编码).

  1. Use an Iterator instead if one is available (never coded for Android so far).

while (iter.hasNext) {
    if (physicsCondition) iter.remove();
}

  • 使用第二个列表来存储要移除的元素,然后再移除它们

  • use a second list to store the elements to remove and remove them afterwards

    List<GraphicsItem> toRemove = new ....
    for (Graphic graphic : lstGraphics) {
        if (physicsCondition) {
            toRemove.add(graphic);
        }
    }
    lstGraphics.removeAll(toRemove);
    

  • 这篇关于Android 动画中的 java.util.ConcurrentModificationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆