2014-07-11 76 views
1

我正在製作一款遊戲,並且在遍歷整個數組時刪除/修改數組列表時發生併發修改異常,但我仍然遇到問題。
我想要刪除對象,當觸摸屏幕和對象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 
        } 
       } 

      } 
     } 
    } 

而且destory方法:

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

而且我把這種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(延伸表面保持器),如下所示:

@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」方法。

+0

也許問題不在於他。請提供您的drawCreatures方法。你在哪裏調用GameView的'run'方法? –

+0

看看現在隊友(: – Pavle37

回答

2

如果你的罰款從迭代器失效的結果,那麼你可以使用的CopyOnWriteArrayList http://developer.android.com/reference/java/util/concurrent/CopyOnWriteArrayList.html

基本上它保證了迭代器顯示,存在內容在當時的迭代器被創建。唯一的變化就是iterator.remove()不能在這個列表返回的迭代器上工作。你必須從實際列表中刪除它。

希望幫助,

納格什

+0

其實這個問題解決了我的問題,謝謝Nagesh。 – Pavle37

0

爲什麼不使用iterator的默認方法?的

it.remove()代替destroy(current);

+0

當然,我已經試過了,但它沒有幫助,得到相同的消息。 – Pavle37

+0

好的,請提供stacktrace。 –