我的Android应用程序有一个IntentService,它从Facebook请求一个MessageThreads对象列表,解析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
和应用程序forcloses。我无法在什么条件下孤立。我读到了这个Exception
,据我所知,当我们在迭代它时从ArrayList
中删除项目时会发生这种情况,但我不会从列表中删除项目。非常感谢任何帮助解决这个问题的指示。
答案 0 :(得分:2)
当您在迭代它时向ArrayList
添加项目时也会发生这种情况,看起来您可能会在此代码中执行此操作。
一般来说,ArrayList
发生的任何“结构修改”都会导致CME在迭代时发生。
答案 1 :(得分:2)
你可以尝试做的是当你迭代你的收藏而不是使用原版时,你可以在那里制作一个副本,所以你会有类似的东西:
for (MessageThread message : new List<MessageThread>(mMessageThreads))
这将帮助您避免CuncurrentModificationException。 现在,如果您真的想要获得幻想,可以使用synchronized块保护您的代码,例如:
synchronized(mMessageThreads){
for (MessageThread message : new List<MessageThread>(mMessageThreads)){
...
}
使用最后一段代码,你将限制对mMessageThreads的访问,如果有人使用它会被锁定,所以如果有人想要使用它,则需要等到第一个完成。