android - 从数组列表中删除对象 - 并发修改异常

标签 android arraylist iterator concurrentmodification

我正在制作游戏,我阅读了所有关于在遍历数组列表时删除/修改数组列表时并发修改异常的内容,但我仍然有问题。
我想在触摸屏幕时删除对象并且对象 x,y 与触摸的 x,y 对齐但是当发生这种情况时,我将触摸的对象放入一个新的集合中以进行删除,但它会删除(有时)对象但是3-4 秒后,这对我来说意义不大,并且还会在 10-15 秒后给出并发修改异常。如果有人注意到我的代码中有任何内容,请告诉我...

public void checkTouch(MotionEvent arg1) {
        int x = (int) arg1.getX();
        int y = (int) arg1.getY();
        synchronized(surfaceHolder){
        /*check every creature for the coordinates*/
        Iterator<Sprite> it = creature.iterator();
        while(it.hasNext())
        {
            Sprite current = it.next();
            int sglX = current.getX();
            int sglY = current.getY();
                if(sglX>=x && x<=(sglX+current.getWidth())){
                    if(sglY>=y && y<=(sglY-current.getHeight())){
                        destroy(current);
                        break; //when we found one object, don't iterate no more
                    }
                }

            }
        }
    }

和销毁方法:

 private void destroy(Sprite removed) {
        /*adds the creature clicked to the recicle bin to be destroyed*/
        recicle.add(removedSeagull); //recicle is the other collection
    }

在 Canvas 上绘制生物之前,我将其称为 creature.removeAll(recicle);,这样它就不会与其他迭代器发生冲突。 这是堆栈跟踪:

07-11 21:06:00.905: E/AndroidRuntime(14221): FATAL EXCEPTION: Thread-83
07-11 21:06:00.905: E/AndroidRuntime(14221): java.util.ConcurrentModificationException
07-11 21:06:00.905: E/AndroidRuntime(14221):    at                  java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
07-11 21:06:00.905: E/AndroidRuntime(14221):    at   com.example.creatures.GameView$GameThread.drawCreatures(GameView.java:292)
07-11 21:06:00.905: E/AndroidRuntime(14221):    at com.example.creatures.GameView$GameThread.doDraw(GameView.java:283)
07-11 21:06:00.905: E/AndroidRuntime(14221):    at com.example.creatures.GameView$GameThread.run(GameView.java:245)

我想可能是绘图方法,所以可能是那里的错误,在这里:

private void drawCreatures(Canvas c) {
        /*iterate through the array and update all the creatures*/
        synchronized(surfaceHolder){
        Iterator<Sprite> it = creature.iterator();
        while(it.hasNext())
        {
            Sprite current = it.next();
            current.draw(c);
        }
        }
    }

GameThread 的 run 方法在 GameView(它扩展了 surface holder)中调用,如下所示:

 @Override
    public void surfaceCreated(SurfaceHolder arg0) {
        thread.setRunning(true);
        thread.start();
    startTimer(1500);
}

线程的运行方法是这样的:

@Override
    public void run(){
        while(run){
            Canvas c = null;
            try {
                c = surfaceHolder.lockCanvas(null);
                synchronized (surfaceHolder) {
                    if (mode == STATE_RUNNING){
                        doDraw(c);
                    }
                }
            } finally {
                // do this in a finally so that if an exception is thrown
                // during the above, don't leave the Surface in an
                // inconsistent state
                if (c != null) {
                    /*unlocks the canvas and shows the image drawn by the doDraw method*/
                    surfaceHolder.unlockCanvasAndPost(c);
                }

在“doDraw”方法中调用了“drawCreatures”方法。

最佳答案

如果您对迭代器的陈旧结果没问题,那么您可以使用 CopyOnWriteArrayList http://developer.android.com/reference/java/util/concurrent/CopyOnWriteArrayList.html

基本上它确保迭代器显示创建迭代器时存在的内容。唯一的变化是 iterator.remove() 不适用于此列表返回的迭代器。您必须将其从实际列表中删除。

希望对你有帮助,

纳格什

关于android - 从数组列表中删除对象 - 并发修改异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24698800/

相关文章:

android - Android 中有效的谷歌帐户 OAuth 2 token

C# int64 列表到字节数组,反之亦然?

java - ArrayList<class> collection.swap 方法

C++ 遍历模板 Map

java - 为什么给我的构造函数的迭代器没有将 iterator.next() 添加到我的列表中?

c++ - 迭代器相等

java - 从 PC 发送到 PC 以及从 PC 发送到 Android 时读取的字节数组不一致

java - 试图在线程中按下PopupWindow的按钮

java - 如何在选中并按下按钮时保存复选框的状态

c# - 在 C# 中计算(复杂的)十进制数数组