2012-05-01 11 views
0

私はOpenGLプログラミングの新機能を使い、簡単なエンジンを作って図面を単純化しました。今、私は加速度計に基づいて変換を行いたい、と私はConcurrentModificationExceptionを得ている。AndroidとOpenGL ES 1.1を使用したConcurrentModificationException

が、ここでは、オブジェクトのクラスです:

public class IbnRushdObject 
{ 
    /** The graphical object to show */ 
    private Mesh mesh = null; 

    /** List of transformations to be executed upon this object */ 
    private List<IbnRushdTransformation> transformations; 

    /** Lock to prevent modification of the list when executing the transformations and viceversa */ 
    private final ReentrantLock lock = new ReentrantLock(); 

    /** 
    * Initializes this IbnRushd object with a mesh 
    * @param mesh 
    */ 
    public IbnRushdObject(Mesh mesh) 
    { 
     this.mesh = mesh; 
    } 

    /** 
    * Adds a transformation to be performed on this object<br> 
    * The transformation does not take place until {@link #moveDraw(GL10)} is called 
    * @param trans 
    */ 
    public void addTransformation(IbnRushdTransformation trans) 
    { 
     try 
     { 
      lock.lock(); 
      if (transformations == null) 
      { 
       transformations = new LinkedList<IbnRushdTransformation>();   
      } 
      transformations.add(trans); 
     } 
     finally 
     { 
      lock.unlock(); 
     } 
    } 

    /** 
    * Executes transformations for this object and draws it 
    * @param gl 
    */ 
    public void moveDraw(GL10 gl) 
    { 
     gl.glMatrixMode(GL10.GL_MODELVIEW); 
     gl.glLoadIdentity(); 

     try 
     { 
      lock.lock(); 
      for(IbnRushdTransformation trans: transformations) // ConcurrentMoificationException thrown here 
      { 
       trans.execute(gl); 
       if (!trans.isPermanent()) 
       { 
        transformations.remove(trans); 
       } 
      } 
     } 
     finally 
     { 
      lock.unlock(); 
     } 

     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL10.GL_COLOR_ARRAY); 

     mesh.draw(gl); 
    } 
} 

moveDraw()メソッドは、描画されるすべてのオブジェクトのリストを保持している

@Override 
public void onDrawFrame(GL10 gl) 
{ 
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
    gl.glClearColor(0, 0.5f, 0.5f, 1.0f); 

    for(IbnRushdObject object : objectQueue) 
    { 
     object.moveDraw(gl); 
    } 
} 

から呼び出されます。

これは、加速度計イベントをリッスンするコードです。リスナーメソッドはonEventChange()です。

public class IbnRushdOrientation implements ServiceListener<Orientation> 
{ 
    private IbnRushdObject object = null; 

    public IbnRushdOrientation(IbnRushdObject obj) 
    { 
     object = obj; 
    } 

    @Override 
    public void onEventChange(Orientation arg0) 
    { 
     IbnRushdRotation hrot = new IbnRushdRotation(); 
     hrot.setFixed(0, 0, 1, 0); 
     hrot.setIncremental((float)arg0.getHorizontalAngle()); 
     hrot.setPermanent(false); 

     IbnRushdRotation vrot = new IbnRushdRotation(); 
     vrot.setFixed(0, 1, 0, 0); 
     vrot.setIncremental((float)arg0.getVerticalAngle()); 
     vrot.setPermanent(false); 

     object.addTransformation(hrot); 
     object.addTransformation(vrot); 
    } 
} 

私はfor(IbnRushdTransformation trans: transformations)でmoveDraw()メソッドにConcurrentModificationExceptionを取得します。

アイデア?前もって感謝します!

答えて

1

オブジェクトを反復処理している間は、オブジェクトをリストから削除することはできません。それが例外の原因です。

forループ(transformations.iterator())の代わりにイテレータを使用してリストを反復した場合、反復処理中にiterator.remove()を呼び出して安全に削除できます。

"Iterator.removeは反復中にコレクションを変更する唯一の安全な方法であり、反復の進行中に基になるコレクションが他の方法で変更されている場合、その動作は不特定です。

http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.html

関連する問題