From 685525513d808b5d3bc171998cfb8258c83a70c0 Mon Sep 17 00:00:00 2001 From: Vetle444 Date: Wed, 4 Mar 2026 10:29:35 +0100 Subject: [PATCH 1/2] done --- CHANGELOG.md | 3 +++ .../Library/Android/FragmentLifeCycleCallback.cs | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 566fc835..38c03007 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [55.2.3] +- [Android][Modal] Fixed crash caused by accessing a disposed Java peer when comparing fragments in OnFragmentDestroyed + ## [55.2.2] - [iOS26][Tip] Added more padding. diff --git a/src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs b/src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs index aef9491f..daf5611d 100644 --- a/src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs +++ b/src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs @@ -46,8 +46,19 @@ public override void OnFragmentDestroyed(FragmentManager fm, Fragment f) { if (s_currentDialogFragmentReferenceStack?.Peek()?.TryGetTarget(out var currentDialogFragment) ?? false) { - if (currentDialogFragment.Equals(dialogFragment)) + try { + if (currentDialogFragment.Handle != IntPtr.Zero && + dialogFragment.Handle != IntPtr.Zero && + currentDialogFragment.Equals(dialogFragment)) + { + s_currentDialogFragmentReferenceStack.Pop(); + } + } + catch (ObjectDisposedException) + { + // The Java peer may already be disposed when OnFragmentDestroyed fires. + // In that case, just pop since the fragment is gone anyway. s_currentDialogFragmentReferenceStack.Pop(); } } From 6dd9263206210c977e4819c474990d01ea3804a6 Mon Sep 17 00:00:00 2001 From: Vetle444 Date: Wed, 4 Mar 2026 10:55:25 +0100 Subject: [PATCH 2/2] ensure we dont have a stale entry --- .../Android/FragmentLifeCycleCallback.cs | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs b/src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs index daf5611d..3be484b3 100644 --- a/src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs +++ b/src/library/DIPS.Mobile.UI/API/Library/Android/FragmentLifeCycleCallback.cs @@ -46,24 +46,30 @@ public override void OnFragmentDestroyed(FragmentManager fm, Fragment f) { if (s_currentDialogFragmentReferenceStack?.Peek()?.TryGetTarget(out var currentDialogFragment) ?? false) { - try + // If either Java peer is already disposed, we can't compare via JNI. + // Since this fragment is being destroyed, pop it to avoid a stale entry. + if (currentDialogFragment.Handle == IntPtr.Zero || dialogFragment.Handle == IntPtr.Zero) { - if (currentDialogFragment.Handle != IntPtr.Zero && - dialogFragment.Handle != IntPtr.Zero && - currentDialogFragment.Equals(dialogFragment)) + s_currentDialogFragmentReferenceStack.Pop(); + } + else + { + try + { + if (currentDialogFragment.Equals(dialogFragment)) + { + s_currentDialogFragmentReferenceStack.Pop(); + } + } + catch (ObjectDisposedException) { s_currentDialogFragmentReferenceStack.Pop(); } } - catch (ObjectDisposedException) - { - // The Java peer may already be disposed when OnFragmentDestroyed fires. - // In that case, just pop since the fragment is gone anyway. - s_currentDialogFragmentReferenceStack.Pop(); - } } + + base.OnFragmentDestroyed(fm, f); } - base.OnFragmentDestroyed(fm, f); } public override void OnFragmentStopped(FragmentManager fm, Fragment f)