java.util.ConcurrentModificationException - ArrayList

To follow up @Rogue's comment, I would look for any instances where any of your notify (notifyDownloadCompleted(), etc.) callback implementations unregister an observer. What can easily happen is that:

1) You're iterating over a collection. While in that iteration, you call a method on one of the registered observers.

2) That registered observer, in the notify callback, calls through to unregister itself from further notifications.

3) Since you're still in that iteration loop, this will cause a ConcurrentModificationException as you cannot modify a collection while iterating over it.

You could fix this by doing a reverse loop:

for (int i = collection.size() - 1; i >= 0; i--) {
    collection.get(i).notifyDownloadCompleted();
}

Although you could technically still run into some edge cases there, but not an exception.


The problem is that you're accessing your ArrayList from another thread, which means when you modify it you get that exception. An easy fix is to replace your ArrayList with a CopyOnWriteArrayList (which is a lot slower), or to use Collections.synchronizedList().

To make a synchronized list:

List<Observer> list = Collection.synchronizedList(new ArrayList<Observer>);

If you are not accessing the collection from multiple threads, but only want to avoid problems when changing the collection while iterating over it, probably the easiest way is to iterate over a copy of your collection instead:

for (Observer observer : new ArrayList<>(observers)) {
  observer.notifyNewLocalBackup(backupInfo);
}

This implies a certain overhead for creating the copy, of course.

You can also use a CopyOnWriteArrayList, which covers the case of access from concurrent threads, too.

Tags:

Java

Android