开发者

java.util.ConcurrentModificationException on surfaceView

im developing a game on android and im having trouble with a loop, that iterates an ArrayList of Zombies. if i substract zombies the app still running, but when i add zombies the app randomly crashes. I i know that the problem starts when i add an item to the zombies ArrayList, and makes that makes the thread throw an exception.

here it is the exception that i got from the 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: 开发者_如何学PythonERROR/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)

And here are the lines where i iterate the zombies ArrayList and if any zombie collides with a sprite it kill them and add a zombie

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

        }

And the die method

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

I tried to use a temp ArrayList, but it throws the same exception, i hope you can understand my ugly english


Separate your logic from doing something and drawing the result on the screen:

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

Code is not tested, just an illustration..


To remove something from a collection while iterating over it, you need to use the remove method from the Iterator. See: http://download.oracle.com/javase/6/docs/api/java/util/Iterator.html

Your code should look something like:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜