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

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

问题描述

也有一些是我很怀念与同步code Android中的概念。

场景

有总是3个项目在屏幕上绘制。每个图像被存储在一个的ArrayList(lstGraphics)。为此我使用SurfaceView。一旦用户点击一个图像上时,图像获取的市场要除去和一个新的将被添加。

code样品:<​​/ P>

AnimationHideThread

  ...
    @覆盖
        公共无效的run(){
            帆布℃;
            而(运行){
                C = NULL;
                尝试 {
                    C = panel.getHolder()lockCanvas(空);
                      同步(panel.getHolder()){

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

                    }
                } 最后 {
                    如果(C!= NULL){
                        panel.getHolder()unlockCanvasAndPost(三);
                    }
                }
            }
        }
...
 

因此​​,大家可以先看起来我updatePhysics()。这意味着我计算的方向,每个图像将移动到。在这里我也从我的列表中删除点击的图像。从那以后,我检查,如果我需要增加一个新的项目在我manageAnimations列表(),然后在最后一步画出了整个事情。

 公共类面板扩展了SurfaceView实现SurfaceHolder.Callback {
....
 公共无效manageAnimations()
    {
          同步(this.getHolder()){
            ...
        而(lstGraphics.size()3;){
                lstGraphics.add(createRandomGraphic());
                }
        }
          }
    }

 @覆盖
    公共布尔的onTouchEvent(MotionEvent事件){
         同步(getHolder()){
            如果(event.getAction()== MotionEvent.ACTION_DOWN){
                 // ...检查是否图像已被点击,然后设置其属性
                        graphic.setTouched(真正的);

                 }
            }

            返回true;
         }
    }

 公共无效updatePhysics(){
       同步(getHolder()){

     对于(图形图形:lstGraphics){
           // ....做一些检查
     如果(graphic.isTouched())
      {
        lstGraphics.remove(图形);
      }
     }
  }
 }

 @覆盖
    公共无效的OnDraw(帆布油画){
         ///绘制背景和lstGraphics每个元素
}

公共类图形{

        私人位图位图;
            私人布尔感动;
            私人坐标initialCoordinates;
....
}
 

我得到的错误是:

 &GT; 10月3号至一日:01:53.365:ERROR / AndroidRuntime(454):未捕获的处理程序:螺纹螺纹-12退出,由于未捕获的异常
&GT; 10月3号至一日:01:53.365:ERROR / AndroidRuntime(454):java.util.ConcurrentModificationException
&GT; 10月3号至一日:01:53.365:ERROR / AndroidRuntime(454):在java.util.AbstractList中的$ SimpleListIterator.next(AbstractList.java:66)
&GT; 10月3号至一日:01:53.365:ERROR / AndroidRuntime(454):在com.test.customcontrols.Panel.updatePhysics(Panel.java:290)
&GT; 10月3号至一日:01:53.365:ERROR / AndroidRuntime(454):在com.test.customcontrols.AnimationHideThread.run(AnimationHideThread.java:41)
 

任何帮助是极大的AP preciated。谢谢你。

解决方案

您的问题是在你的物理方法,在其中添加了图形和列表

 公共无效updatePhysics(){
    同步(getHolder()){
        对于(图形图形:lstGraphics){
        // ....做一些检查
        如果(graphic.isTouched()){
            lstGraphics.remove(图形); //你的问题
        }
    }
}
 

的(平面图形:lstGraphics)相结合 lst.Graphics.remove(图形); 的原因因为你是运行在你的清单,同时将ConcurrentModificationException的尝试对其进行修改。

到目前为止,我知道两个解决方案:

  1. 使用迭代器而不是(如果有)(从未codeD为Android到目前为止)。

     而(iter.hasNext){
        如果(physicsCondition)iter.remove();
    }
     

  2. 使用第二个列表来存储内容删除,之后将其删除

     名单,其中,GraphicsItem&GT;的文档,删除=新....
    对于(图形图形:lstGraphics){
        如果(physicsCondition){
            toRemove.add(图形);
        }
    }
    lstGraphics.removeAll(文档,删除);
     

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

Scenario

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.

Code samples:

AnimationHideThread

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

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

The error I get is:

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

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. Use an Iterator instead if one is available (never coded for Android so far).

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

  2. 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);
    

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

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