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;
}
精彩评论