Skip to content

[cherry-pick][4.2] Fix commits during the Android draw pass#9123

Merged
bartlomiejbloniarz merged 2 commits into
4.2-stablefrom
@bartlomiejbloniarz/android-draw-cherry-pick-4.2
Mar 20, 2026
Merged

[cherry-pick][4.2] Fix commits during the Android draw pass#9123
bartlomiejbloniarz merged 2 commits into
4.2-stablefrom
@bartlomiejbloniarz/android-draw-cherry-pick-4.2

Conversation

@bartlomiejbloniarz

Copy link
Copy Markdown
Collaborator

Cherry picks #9078 and #9072

bartlomiejbloniarz and others added 2 commits March 18, 2026 16:10
## Summary

Separates the synchronous UI props update logic into its own
`applySynchronousUpdates` method.

Adds `partitionUpdates` and
`shouldUseSynchronousUpdatesInPerformOperations` helpers to support the
extracted method.

## Test plan
## Summary

This PR intends to solve the most annoying crash that we currently face on Android. The crash is caused by Reanimated calling `ShadowTree::commit` when handling events that were emitted while in the Android drawing pass.

Performing a commit can cause other changes queued by React Native to also get applied. This can lead to the view hierarchy being modified, which is not allowed while in the draw pass.

To fix this, we have a workaround where if we are in the draw pass, we instead only apply non-layout changes (that can be applied without a ShadowTree commit), and schedule the layout changes to happen when we are outside of the draw call. We want to apply the non-layout updates there to maintain things like transform driven sticky headers.

closes #8422 🤞

## Test plan

I added a new Android Draw Pass example, it would also make sense to test the sticky header and other event related examples
@bartlomiejbloniarz bartlomiejbloniarz changed the title Fix commits happening during the Android draw pass [cherry-pick] Fix commits happening during the Android draw pass Mar 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Cherry-picks upstream fixes to prevent Reanimated from committing Fabric ShadowTree updates during the Android draw pass (a known crash scenario), by splitting “layout” vs “non-layout” updates and deferring layout-affecting commits until the next frame. It also refactors synchronous UI prop updates into a dedicated helper for better reuse.

Changes:

  • Refactors performOperations to remove the “triggered by event” boolean and extracts synchronous-props logic into applySynchronousUpdates (+ partitionUpdates / feature-flag helper).
  • Adds Android draw-pass detection (DrawPassDetector) and a “non-layout operations only” pathway invoked when events arrive during draw.
  • Adds an Android Draw Pass example screen and tweaks StickyHeaderExample to exercise layout changes during scroll.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/react-native-reanimated/apple/reanimated/apple/native/NativeProxy.mm Updates call site for new performOperations() signature
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NodesManager.java Adds draw-pass-aware operation execution + new non-layout path
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/NativeProxy.java Updates native method signatures + routes flush via draw-pass-aware path
packages/react-native-reanimated/android/src/main/java/com/swmansion/reanimated/DrawPassDetector.java New helper to track whether UI thread is currently in a draw pass
packages/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.h Updates native proxy API (adds non-layout ops)
packages/react-native-reanimated/android/src/main/cpp/reanimated/android/NativeProxy.cpp Implements/exports new JNI methods for non-layout ops
packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.h Updates public API + adds private applySynchronousUpdates
packages/react-native-reanimated/Common/cpp/reanimated/NativeModules/ReanimatedModuleProxy.cpp Extracts synchronous updates; adds non-layout-only entrypoint
packages/react-native-reanimated/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.h Adds getPendingUpdates() API
packages/react-native-reanimated/Common/cpp/reanimated/Fabric/updates/UpdatesRegistry.cpp Implements getPendingUpdates()
apps/fabric-example/ios/Podfile.lock Updates CocoaPods checksums from cherry-pick
apps/common-app/src/apps/reanimated/examples/index.ts Registers new Android Draw Pass example
apps/common-app/src/apps/reanimated/examples/StickyHeaderExample.tsx Adds animated width to force layout updates during scroll
apps/common-app/src/apps/reanimated/examples/AndroidDrawPassExample.tsx New example demonstrating the historical crash + fix

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@bartlomiejbloniarz bartlomiejbloniarz changed the title [cherry-pick] Fix commits happening during the Android draw pass [cherry-pick][4.2] Fix commits during the Android draw pass Mar 18, 2026
@bartlomiejbloniarz bartlomiejbloniarz merged commit e161f81 into 4.2-stable Mar 20, 2026
42 of 53 checks passed
@bartlomiejbloniarz bartlomiejbloniarz deleted the @bartlomiejbloniarz/android-draw-cherry-pick-4.2 branch March 20, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants