From 5c26178be8e67bfee06129217ec49581a4bafeea Mon Sep 17 00:00:00 2001 From: Jay Koutavas Date: Fri, 16 May 2025 08:54:06 -0400 Subject: [PATCH] Fix ConcurrentModificationException in InteropUIBlockListener --- .../interop/InteropUiBlockListener.kt | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt index 5435a35dbe1346..b361b613a79863 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/internal/interop/InteropUiBlockListener.kt @@ -42,24 +42,38 @@ internal class InteropUIBlockListener : UIManagerListener { if (beforeUIBlocks.isEmpty()) { return } - beforeUIBlocks.forEach { - if (uiManager is UIBlockViewResolver) { - it.execute(uiManager) + // avoid ConcurrentModificationException by iterating over a copy + try { + val snapshot = ArrayList(beforeUIBlocks) + snapshot.forEach { block -> + if (uiManager is UIBlockViewResolver) { + block.execute(uiManager) + } } + } catch (e: ConcurrentModificationException) { + // ignore any mid-iteration mutations + } finally { + beforeUIBlocks.clear() } - beforeUIBlocks.clear() } override fun didMountItems(uiManager: UIManager) { if (afterUIBlocks.isEmpty()) { return } - afterUIBlocks.forEach { - if (uiManager is UIBlockViewResolver) { - it.execute(uiManager) + // avoid ConcurrentModificationException by iterating over a copy + try { + val snapshot = ArrayList(afterUIBlocks) + snapshot.forEach { block -> + if (uiManager is UIBlockViewResolver) { + block.execute(uiManager) + } } + } catch (e: ConcurrentModificationException) { + // ignore any mid-iteration mutations + } finally { + afterUIBlocks.clear() } - afterUIBlocks.clear() } override fun didDispatchMountItems(uiManager: UIManager) = didMountItems(uiManager)