Commit 5e6ff91
fix(android): guard null Handler in ButtonViewGroup press animations (#4294)
## Description
On Android, `ButtonViewGroup` uses the view's Handler (via
`View.getHandler()`) to schedule and cancel the delayed press-out
animation. That getter returns null while the view is detached from the
window, so when a cancel event is delivered to a button that has just
been detached, `animatePressOut` crashes with a NullPointerException.
The crash path is: the orchestrator cancels the native handler, which
dispatches a cancel event back to the button, which runs
`setPressed(false)` → `animatePressOut()` and dereferences the now-null
handler.
This guards the four handler accesses (in `animatePressIn`,
`animatePressOut` and `onDetachedFromWindow`) with a null check. When
the view is detached there is nothing meaningful to schedule or cancel
and no visible animation to play, so skipping the call is the correct
behavior; while attached the getter is non-null and behavior is
unchanged.
Additionally, `onDetachedFromWindow` now runs its cleanup (cancelling
`pendingPressOut`, resetting press/hover state) before calling
`super.onDetachedFromWindow()`, so the pending runnable is removed while
the view is still fully attached and the handler is guaranteed to be
available (addresses the review note about reading the handler after
`super` during detach).
Closes #4293
## Test plan
The crash is a detach/cancel race captured in production via Sentry, so
it has no deterministic repro. The change only adds null-safety around
`View.getHandler()`, which is null exactly while the view is detached:
- Attached (normal) case: the getter is non-null, so press-in and
press-out animation scheduling behaves exactly as before.
- Detached case: the affected `removeCallbacks`/`postDelayed` calls are
skipped instead of throwing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 28a4c99 commit 5e6ff91
1 file changed
Lines changed: 6 additions & 5 deletions
File tree
- packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react
Lines changed: 6 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
707 | 707 | | |
708 | 708 | | |
709 | 709 | | |
710 | | - | |
| 710 | + | |
711 | 711 | | |
712 | 712 | | |
713 | 713 | | |
| |||
766 | 766 | | |
767 | 767 | | |
768 | 768 | | |
769 | | - | |
| 769 | + | |
770 | 770 | | |
771 | 771 | | |
772 | 772 | | |
| |||
794 | 794 | | |
795 | 795 | | |
796 | 796 | | |
797 | | - | |
| 797 | + | |
798 | 798 | | |
799 | 799 | | |
800 | 800 | | |
| |||
910 | 910 | | |
911 | 911 | | |
912 | 912 | | |
913 | | - | |
914 | | - | |
| 913 | + | |
915 | 914 | | |
916 | 915 | | |
917 | 916 | | |
| |||
925 | 924 | | |
926 | 925 | | |
927 | 926 | | |
| 927 | + | |
| 928 | + | |
928 | 929 | | |
929 | 930 | | |
930 | 931 | | |
| |||
0 commit comments