0

私の Android アプリには、Facebook から MessageThreads オブジェクトのリストを要求する IntentService があり、JSON 応答を解析してオブジェクトの ArrayList を構築します。

ArrayList<MessageThread> mMessageThreads = new ArrayList<MessageThread>();

次に、同じサービスで FB を再度呼び出し、MessageThread ID の名前を取得して、それらを MessageThread オブジェクトと照合します。この時点で、完全な MessageThread オブジェクトを含む ArrayList があり、それらを SQLite データベースに挿入します。

// save to db and broadcast
for (MessageThread message : mMessageThreads) {
    ((FBClientApplication)getApplication()).getMessagesData().insertOrIgnore(message.toContentValues();
}

どこ:

public void insertOrIgnore(ContentValues values) {
    SQLiteDatabase db = this.dbHelper.getWritableDatabase();
    db.insertWithOnConflict(TABLE, null, values, SQLiteDatabase.CONFLICT_IGNORE);
}

ACRA レポートを介して、断続的にラインが表示されます

for (MessageThread message : mMessageThreads) 

をスローしConcurrentModificationException、アプリを閉じます。どのような条件で隔離できなかったのか。私はこれについて読みましたが、繰り返し処理中にExceptionアイテムを削除すると発生することを理解していますが、リストからアイテムを削除していません。ArrayListこの問題を解決するためのポインタは大歓迎です。

4

2 に答える 2

2

あなたがしようとすることができるのは、元のコレクションを使用する代わりにコレクションを反復するときに、すぐにコピーを作成できるため、次のようなものになります。

for (MessageThread message : new List<MessageThread>(mMessageThreads))

これにより、CuncurrentModificationException を回避できます。本当に凝りたい場合は、次のような同期ブロックを使用してコードを保護できます。

synchronized(mMessageThreads){
    for (MessageThread message : new List<MessageThread>(mMessageThreads)){
    ...
}

この最後のコードでは、mMessageThreads へのアクセスを制限します。誰かが使用している場合はロックされます。他の誰かが使用したい場合は、最初のスレッドが完了するまで待つ必要があります。

于 2013-02-07T03:36:15.287 に答える
2

ArrayListこれは、このコードで行っているように、アイテムを反復処理中に に追加するときにも発生します。

ArrayList一般に、反復中に CME を引き起こす可能性があるのは、 に発生する「構造変更」です。

于 2013-02-07T00:20:04.077 に答える