From ee8a0cfa5a348ac00acd40d19ab9019e21115149 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Fri, 17 Jul 2020 11:49:15 -0700 Subject: [PATCH] Fix ConcurrentModificationException while registering events Summary: This diff fixes a ConcurrentModificationException that is thrown when registering events in React Native. This bug was introduced by D22483508 (https://github.com/facebook/react-native/commit/80f13412e548c8666b6ad770e6d3d5c54a717bc2), before event listeners were registered in the NativeModule Thread, now they are registered in the UI Thread. As part of this diff I change the type of mListeners variable to use CopyOnWriteArrayList instead of ArrayList because this variable is accessed from different threads. This will prevent the exception to happen, but additionally we need to verify if the change of threading made in D22483508 (https://github.com/facebook/react-native/commit/80f13412e548c8666b6ad770e6d3d5c54a717bc2) will cause any other issue (e.g. events not being delivered becuase the listeners are registered too late in the UI Thread) changelog:[Internal] Reviewed By: JoshuaGross Differential Revision: D22599747 fbshipit-source-id: 5c5e46710c4a559badbd713f536e6e6e464fda23 --- .../facebook/react/uimanager/events/EventDispatcherImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java index 542f03616f1..9754b2de085 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicInteger; /** @@ -88,7 +89,8 @@ public class EventDispatcherImpl implements EventDispatcher, LifecycleEventListe private final Map mEventNameToEventId = MapBuilder.newHashMap(); private final DispatchEventsRunnable mDispatchEventsRunnable = new DispatchEventsRunnable(); private final ArrayList mEventStaging = new ArrayList<>(); - private final ArrayList mListeners = new ArrayList<>(); + private final CopyOnWriteArrayList mListeners = + new CopyOnWriteArrayList<>(); private final List mPostEventDispatchListeners = new ArrayList<>(); private final ScheduleDispatchFrameCallback mCurrentFrameCallback = new ScheduleDispatchFrameCallback();