Reputation: 1127
My Android app has an IntentService where it requests a list of MessageThreads objects from Facebook, parses the JSON response to build an ArrayList of the objects:
ArrayList<MessageThread> mMessageThreads = new ArrayList<MessageThread>();
Then it calls FB again in the same service, get the names for the MessageThread ids and matches them with the MessageThread objects. At this point I have an ArrayList with complete MessageThread objects and I insert them into an SQLite db.
// save to db and broadcast
for (MessageThread message : mMessageThreads) {
((FBClientApplication)getApplication()).getMessagesData().insertOrIgnore(message.toContentValues();
}
where:
public void insertOrIgnore(ContentValues values) {
SQLiteDatabase db = this.dbHelper.getWritableDatabase();
db.insertWithOnConflict(TABLE, null, values, SQLiteDatabase.CONFLICT_IGNORE);
}
Via ACRA reports I see that intermittently the line
for (MessageThread message : mMessageThreads)
throws an ConcurrentModificationException
and the app forcloses. I haven't been able to isolate under what conditions. I read about this Exception
and as I understand it it happens when we remove items from an ArrayList
while iterating over it, but I'm not removing items from the list. Any pointers to help with this problem are greatly appreciated.
Upvotes: 0
Views: 201
Reputation: 262
What you can try to do is when you iterates your Collection instead of using the original you can make a copy right there, so you will have something like:
for (MessageThread message : new List<MessageThread>(mMessageThreads))
That will help you to avoid CuncurrentModificationException. Now if you really want to get fancy you can protect your code using synchronized blocks such as:
synchronized(mMessageThreads){
for (MessageThread message : new List<MessageThread>(mMessageThreads)){
...
}
With this last pice of code you will restrict the access to mMessageThreads, if somebody it's using it it will get locked, so if somebody else wants to use it needs to wait until the first one is done.
Upvotes: 2
Reputation: 198014
It also happens when you add items to an ArrayList
while iterating over it, which it looks like you might do in this code.
In general, it's any "structural modification" that occurs to the ArrayList
that can cause a CME while iterating.
Upvotes: 2