Commit 53369ed
Skip dropped mapped node in PropsAnimatedNode.updateView instead of crashing (#57298)
Summary:
`PropsAnimatedNode.updateView()` iterates its mapped property nodes every frame and calls `requireNotNull(node) { "Mapped property node does not exist" }` for each one. When a connected component is unmounted (for example during a navigation transition), its child animated nodes can be dropped from `NativeAnimatedNodesManager` while a frame callback for the prop node is still in flight. On the next `updateView` the mapped node is gone, `requireNotNull` throws, and the app crashes:
```
java.lang.IllegalArgumentException: Mapped property node does not exist
at com.facebook.react.animated.PropsAnimatedNode.updateView(PropsAnimatedNode.kt)
at com.facebook.react.animated.NativeAnimatedNodesManager.updateNodes(NativeAnimatedNodesManager.java)
at com.facebook.react.animated.NativeAnimatedNodesManager.runUpdates(NativeAnimatedNodesManager.java)
```
This is a teardown race: by the time the mapped node has been removed, the connected view is being torn down, so there is no meaningful value to write for that prop on this frame. This change skips a missing mapped node instead of throwing.
It mirrors the guard already at the top of the same method, which returns early when the view itself is gone (`connectedViewTag == -1`), and matches the lenient behavior on iOS, where `RCTPropsAnimatedNode` iterates its parent nodes with `isKindOfClass:` checks and a missing (`nil`) node is simply skipped.
Fixes #37267.
## Changelog:
[ANDROID] [FIXED] - Prevent "Mapped property node does not exist" crash in `PropsAnimatedNode.updateView` when a mapped node is removed during an in-flight native animation
Pull Request resolved: #57298
Test Plan:
The crash is a timing-dependent race, so it reproduces probabilistically rather than deterministically. Using the repro from #37267 (a screen with many simultaneous native-driver animations, navigating in and out repeatedly) and increasing **Animator duration scale** in Developer Options widens the window and makes it reproduce reliably on lower-end devices.
- **Before:** rapidly navigating away from a screen with running native-driver animations crashes with `IllegalArgumentException: Mapped property node does not exist`.
- **After:** the stale node is skipped and no crash occurs.
- **Happy path unaffected:** when all mapped nodes are present, behavior is identical. The change only adds an early `continue` for the already-removed-node case, so no prop update is lost for live nodes.
Reviewed By: zeyap, christophpurrer
Differential Revision: D109253948
Pulled By: fabriziocucci
fbshipit-source-id: 76c1a4c89e7cdd4476a31866d4871e90ddb983241 parent dc4d5e8 commit 53369ed
2 files changed
Lines changed: 25 additions & 1 deletion
File tree
- packages/react-native/ReactAndroid/src
- main/java/com/facebook/react/animated
- test/java/com/facebook/react/animated
Lines changed: 6 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
78 | | - | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
79 | 84 | | |
80 | 85 | | |
81 | 86 | | |
| |||
Lines changed: 19 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
167 | 186 | | |
168 | 187 | | |
169 | 188 | | |
| |||
0 commit comments