2012-04-17 8 views
2

私はConcurrentModificationExeptionを単一のスレッドケースとみなして取得しました。また、リストを反復してループ内でそれを修正しようとすると、例外が発生することも知っています。したがって、実際にはイテレータを使用してイテレートして変更します。しかし、私はまだ例外があります。Android ArrayListのIteratorを使用してもConcurrentModificationExceptionが発生する

基本的には、アニメーションマネージャを実装しており、すべてのIAnimationオブジェクトをArrayListに格納しています。リストを変更するpublicメソッドはaddAnimationです。これはリストをループする別のメソッドで、calculateTickです。両方のメソッドが同期されているので、私はスレッドの問題があるとは思わない。そして先に述べたように、私はイテレータを使ってループを繰り返します。あなたは私にこの例外がある理由を知っていますか?ここで

は私のコードです:

private List<IAnimation> animations = new ArrayList<IAnimation>(); 
    public synchronized void addAnimation(IAnimation animation) { 
    animations.add(animation); 
    mLooper.update(); 
    inAnimation = true; 
} 

public synchronized void calculateTick(float tpf) {  
    for (Iterator<IAnimation> iterator = animations.iterator(); iterator.hasNext();) { 
     IAnimation animation= iterator.next(); 
        boolean animateMore = animation.calculateTick(tpf); 
     if (!animateMore) {{ 
      iterator.remove(); 
     } 
    } 

} 

そして、ここでは私の例外です:

E/AndroidHarness(9546): Exception thrown in Thread[GLThread 1260,5,main] 

4月17日11:55:38.001:E/AndroidHarness(9546):java.util.ConcurrentModificationExceptionが 04-17 11:55:38.001:E/AndroidHarness(9546):java.util.ArrayList $ ArrayListIterator.remove(ArrayList.java:582) 04-17 11:55:38.001:E/AndroidHarness(9546) :com.avaya.mco.gui.animation.AnimationManager.calculateTick(AnimationManager.java:50) 04-17 11:55:38.001:E/AndroidHarness(9546):com.avaya.mco.gui.jmonkey.android.MyApplication.simpleUpdate(MyApplication.java:60) 04-17 11:55:38.001: E/AndroidHarness(9546):at ......

+0

今はリストのコピーを繰り返して、元のものから削除する必要があります。しかし、私はこの場合ArrayListIteratorが動作するはずだと思います。それがアンドロイドのバグかどうか分かりませんか? – trungdinhtrong

+0

他の何かがリストを読んでいたり、変更したりしています。これは実装のバグよりはるかに可能です。 –

+0

あなたは正しいです。そのループの中には、最終的にリストに変更が生じる場所があります。悲しいことに、私のコードはバグである可能性が高いと既に知っていましたが、他の人がもう一度それを助けていることを助けているのです。 – trungdinhtrong

答えて

0

ここに欠けている機能はないのですか?アニメーションを再生する何か?

も、それは「ConcurrentLinkedQueue」を使ってみて、問題が解決しない場合: http://developer.android.com/reference/java/util/concurrent/ConcurrentLinkedQueue.html それはすべてのバージョンで利用可能だし、それはイテレータのためのことを言う: 『弱一貫性」...返された反復子があります』 ConcurrentModificationExceptionを投げることはなく、イテレータの構築時に存在していた要素をトラバースすることを保証し、構築後の変更を反映するかもしれない(ただし保証されない)イテレータ。

+0

ありがとうございます。そこに欠けている機能はありませんが、リストを反復します。そのループは、アニメーションを再生するループです。しかし、アニメーションのコードの中には、リストにアニメーションを追加した場所があります。したがって、ループ自体の内部には、アニメーションがリストに追加され、iterator.remove()が呼び出されて例外が発生するという点があります。 ConcurrentLinkedQueueを使用すると、実際には例外も解決するはずです。 – trungdinhtrong

+0

それはコレクションに何かを追加していた別のスレッドだったでしょうか? –

+0

いいえ、実際は同じスレッドでした。それは同じループで起こります。私にとっての問題は、予期せぬ場所で呼び出し元のツリーの中に非常に深いところがあり、最初はそれが全く見えなかったということでした。 – trungdinhtrong

関連する問題