fix android 8 screen crash

This commit is contained in:
Samuel Newman
2026-08-31 22:53:50 +03:00
parent 0a00392b65
commit 393b40e493
3 changed files with 59 additions and 12 deletions
+29
View File
@@ -31,3 +31,32 @@ index 76bb694854b29d7f779f38244cd48113b429ea1f..fd402ac938862e8d39c5467c1b5c86c4
startTransitionRecursive(child)
}
}
diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt b/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt
index 9f9f8647a50a537d9eec0643db5be69d05089688..09390fc732652ec63b78dbaf2e877b5063886706 100644
--- a/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt
+++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt
@@ -419,7 +419,23 @@ class ScreenStack(
private fun performDraw(op: DrawingOp) {
// Canvas parameter can not be null here https://developer.android.com/reference/android/view/ViewGroup#drawChild(android.graphics.Canvas,%20android.view.View,%20long)
// So if we are passing null here, we would crash anyway
- super.drawChild(op.canvas!!, op.child, op.drawingTime)
+ val child = op.child!!
+ try {
+ super.drawChild(op.canvas!!, child, op.drawingTime)
+ } catch (exception: NullPointerException) {
+ // Deferred draws can outlive a child's attachment. Android 8.1 can then dereference
+ // cleared attachment state while applying the child's legacy animation.
+ val topFrame = exception.stackTrace.firstOrNull()
+ val isDetachedViewLegacyAnimationCrash =
+ Build.VERSION.SDK_INT == Build.VERSION_CODES.O_MR1 &&
+ !child.isAttachedToWindow &&
+ topFrame?.className == View::class.java.name &&
+ topFrame.methodName == "applyLegacyAnimation"
+
+ if (!isDetachedViewLegacyAnimationCrash) {
+ throw exception
+ }
+ }
}
// Can't use `drawingOpPool.removeLast` here due to issues with static name resolution in Android SDK 35+.
@@ -13,3 +13,21 @@ The patch transitions a RecyclerView as a single unit without recursively transi
Related issues:
- https://github.com/callstack/react-native-pager-view/issues/1005
- https://github.com/software-mansion/react-native-screens/issues/2461
## Android 8.1: ignore detached legacy-animation draws
Fixes a framework `NullPointerException` in `View.applyLegacyAnimation` when opening a post on Android 8.1.
`ScreenStack` defers child drawing so it can reorder disappearing screens. A child can be detached between the original `drawChild()` call and the deferred draw. Android 8.1 can then dereference cleared attachment state while applying that child's legacy animation.
The patch ignores only the known framework crash when all of these conditions hold:
- the device is running Android 8.1;
- the child is no longer attached to a window; and
- the top exception frame is `android.view.View.applyLegacyAnimation`.
All other `NullPointerException`s are rethrown.
Related issues:
- APP-2982
- https://blueskyweb.sentry.io/issues/APP-T4Z8