surfaceView上的java.util.ConcurrentModificationException

时间:2011-07-20 00:12:22

标签: android

我正在Android上开发一款游戏,我遇到了循环问题,它会迭代僵尸的ArrayList。如果我减去僵尸应用程序仍在运行,但当我添加僵尸时,应用程序随机崩溃。 我知道当我向僵尸ArrayList添加一个项目时问题就开始了,这使得线程抛出异常。

这是我从LogCat获得的例外

07-19 20:55:02.960: ERROR/AndroidRuntime(19526): FATAL EXCEPTION: Thread-9
07-19 20:55:02.960: ERROR/AndroidRuntime(19526): java.util.ConcurrentModificationException
07-19 20:55:02.960: ERROR/AndroidRuntime(19526):     at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
07-19 20:55:02.960: ERROR/AndroidRuntime(19526):     at com.funkytron.android.killthemall.GameView.onDraw(GameView.java:131)
07-19 20:55:02.960: ERROR/AndroidRuntime(19526):     at com.funkytron.android.killthemall.GameLoopThread.run(GameLoopThread.java:34)

以下是我对zombies ArrayList进行迭代的行,如果有任何僵尸与精灵发生碰撞,它会杀死它们并添​​加一个僵尸

        for (Iterator<Zombie> zombieIterator = zombieCollection.iterator(); zombieIterator.hasNext();)
        {
            Zombie zombie = zombieIterator.next();
                zombie.onDraw(canvas);

                for(Iterator<Sprite> sprite = sprites.iterator(); sprite.hasNext();)
                {
                    Sprite s = sprite.next();
                    if(zombie.isCollision(s.getX(), s.getY()))
                    {
                        die(s, zombie.getX(), zombie.getY());
                        break;
                    }
                }

        }

和模具方法

public void die(Sprite sprite, float x, float y)
{
    sprites.remove(sprite);
    zombieCollection.add(createZombie(R.drawable.zombie,0,0));
    temps.add(new TempSprite(temps, this, x, y, bmpBlood));
    addPoints = true;
}

我尝试使用临时ArrayList,但它抛出相同的异常,我希望你能理解我的丑陋英语

2 个答案:

答案 0 :(得分:2)

将你的逻辑与做某事分开并在屏幕上绘制结果:

for (Zombie zombie :  zombieCollection) {
    for (Sprite sprite : sprites) {
        if (zombie.isCollision(sprite.getX(), sprite.getY())) {
            sprite.markAsZombified();
            break;
        }
    }
}

for (Iterator<Sprite> spriteIterator = sprites.iterator(); sprite.hasNext();) {
    Sprite sprite = spriteIterator.next();
    if (sprite.isZombified()) {
         spriteIterator.remove();
         Zombie newZombie = createZombie();
         zombieCollections.add(newZombie);
    }
}

for (Zombie zombie :  zombieCollection) {
    zombie.onDraw(canvas);
}

代码未经过测试,只是一个插图..

答案 1 :(得分:0)

要在迭代时从集合中删除某些内容,您需要使用迭代器中的remove方法。请参阅:http://download.oracle.com/javase/6/docs/api/java/util/Iterator.html

您的代码应该类似于:

for (Zombie zombie :  zombieCollection)
{

      zombie.onDraw(canvas);

        for(Iterator<Sprite> spriteIterator = sprites.iterator(); sprite.hasNext();)
        {
            Sprite s = spriteIterator.next();
            if(zombie.isCollision(s.getX(), s.getY()))
            {
                die(spriteIterator, zombie.getX(), zombie.getY());
                break;
            }
        }

}

public void die(Iterator spriteIterator, float x, float y)
{
    spriteIterator.remove();
    zombieCollection.add(createZombie(R.drawable.zombie,0,0));
    temps.add(new TempSprite(temps, this, x, y, bmpBlood));
    addPoints = true;
}