2

ランゲージArrayListを以下のロジックに従って、Runnableを通じてバックグラウンドスレッドで実行しています。関連するコードのみを表示するようにコードを編集しました。私はConcurrentModificationExceptionを得ています。onLocationMethodからConcurrentModificationExceptionを取得する

public static ArrayList<Location> locationPoints; 


@Override 
public void onLocationChanged(final Location location) { 
    //Log.i(TAG, "onLocationChanged: " + location); 
    Log.i(TAG, "onLocationChanged: " + locationPoints.size()); 

    ArrayList<Location> alnew= locationPoints; 

    if(!locationPoints.isEmpty()){ 
     for(Location l:alnew){ 
      if(location.distanceTo(l)<=200.0f){ 
       locationPoints.add(l); 
      }else{ 
       locationPoints.add(location); 
      } 
     } 
    }else{ 
     locationPoints.add(location); 
    } 

    sendLocationsToActivity(locationPoints); 
} 

私は場所のオブジェクトが次々に行きつくようにしたいが、私は指数関数的に増加する位置オブジェクトを見る。

onLocationChangedの結果は以下のとおりです。例外はArrayListメソッドから発生していますが、ここで示したすべての措置を使用しても解決策を見つけることができません。

onLocationChanged:0
onLocationChanged:1
onLocationChanged:2
onLocationChanged:4
onLocationChanged:8
onLocationChanged:32

しかし、私は削除した場合、すべての:16
onLocationChanged ArrayListロジックをonLocationChangedから削除し、単に場所objを追加します0
onLocationChanged:1
onLocationChanged:2
onLocationChanged:3
onLocationChanged:4
onLocationChanged:5

ArrayListにECTSは、結果は私が

onLocationChangedをしたい方法です

StackTrace:

FATAL EXCEPTION: main 
Process: com.amreen.test, PID: 27053 
Theme: themes:{default=overlay:com.resurrectionremix.pitchblack, fontPkg:com.resurrectionremix.pitchblack, com.android.systemui=overlay:com.resurrectionremix.pitchblack, com.android.systemui.headers=overlay:com.resurrectionremix.pitchblack, com.android.systemui.navbar=overlay:com.resurrectionremix.pitchblack} 
java.util.ConcurrentModificationException 
    at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573) 
    at com.amreen.test.MyLocationService.onLocationChanged(MyLocationService.java:146) 
    at com.google.android.gms.location.internal.zzk$zzb.handleMessage(Unknown Source) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5458) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
+0

は、例外のトレースをスタック、およびHTTP(あなたのコードを最小限にし、[*最小*、完全、かつ検証例]を提供してみてください(ショート)を提供してください://stackoverflow.com/help/mcve)。他のConcurrentModificationExceptionの質問を検索しましたか?このトピックには多くのリソースがあります。 –

+0

私は指示通りに変更を加えました。 – user7090887

+1

Iteratorを使用してリストをトラバースしているときに、リストの変更(要素の追加または削除)を行うとConcurrentModificationExceptionが発生します。ここでfor-eachループは内部的にイテレータを利用しています。あなたは別のarraylistを使用して、その要素を保持し、ループから抜け出して元のコレクションを更新する必要があります。 –

答えて

2

Iteratorを使用してリストをトラバースしているときに、リストを変更(要素の追加または削除)すると、ConcurrentModificationExceptionが発生します。 for-eachループは、java.util.Iteratorの構文上の砂糖です。だからここのロジックは次のようである:

for() { 
    if(someCondition) { 
     locationPoints.add(sth); 
    } 
} 

よりもむしろあなたが好きかなっ試みることができること:

ループのうち
for() { 
     if(someCondition) { 
      someOtherArrayList.add(sth); 
     } 
    } 

そして、一度、すべてをそれから:

locationPoints.addAll(someOtherArrayList); 
+0

コードを更新しましたが、問題が解決しない場合は、新しいarrayListを作成したかどうかを確認してください。しかし、このコメントを書いている間、私は同じオブジェクトを参照することを間違えたことを実感します。私はあなたの指示に従って努力します。 – user7090887

+0

あなたのメソッドは例外を解決しましたが、奇妙な結果がまだ続きます – user7090887

1

ことがあるので、 ArrayListの実装については、 ArrayList document

を参照してください。

このクラスのiteratorメソッドとlistIteratorメソッドから返されるイテレータは、フェイルファーストです。イテレータの作成後、イテレータの独自のremoveメソッドまたはaddメソッド以外の方法でリストが構造的に変更された場合、イテレータはConcurrentModificationException。したがって、同時の変更に直面して、イテレータは、未定義の時間に任意の非決定論的な動作を将来的に危険にさらすのではなく、迅速かつきれいに失敗します。

まず、イテレータを取得してから追加します。 例

Iterator<Location> iter = locationPoints.iterator(); while (iter.hasNext()) { Location location = iter.next(); if(location.distanceTo(l)<=200.0f){ iter.add(l); }else{ iter.add(location); } }

関連する問題