Fix for BlazorWebView Back Navigation Issues on Android 13+ After Predictive Back Gesture Changes#33213
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes BlazorWebView back navigation on Android 13+ by implementing an OnBackPressed lifecycle event handler that checks for WebView navigation history before allowing page navigation. The fix extends the predictive back gesture support introduced in PR #32461 to include BlazorWebView components, and adds a cleanup mechanism for lifecycle event handlers to prevent memory leaks.
Key Changes
- Adds OnBackPressed handler registration in BlazorWebViewHandler.ConnectHandler that checks WebView.CanGoBack() before allowing page pop
- Implements RemoveEvent method in LifecycleEventService to support proper handler cleanup in DisconnectHandler
- Updates public API surface to track the new ConnectHandler override
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| src/Core/src/LifecycleEvents/LifecycleEventService.cs | Adds internal RemoveEvent method to enable lifecycle event handler cleanup |
| src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs | Implements ConnectHandler/DisconnectHandler overrides to register/unregister OnBackPressed handler for WebView back navigation |
| src/BlazorWebView/src/Maui/PublicAPI/net-android/PublicAPI.Unshipped.txt | Tracks new ConnectHandler override as public API surface change |
src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs
Outdated
Show resolved
Hide resolved
src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs
Outdated
Show resolved
Hide resolved
| var lifecycleService = MauiContext.Services.GetService<ILifecycleEventService>(); | ||
| if (lifecycleService is LifecycleEventService concreteService) | ||
| { | ||
| concreteService.RemoveEvent(nameof(AndroidLifecycle.OnBackPressed), _onBackPressedHandler); | ||
| _onBackPressedHandler = null; | ||
| } |
There was a problem hiding this comment.
The same cast pattern (ILifecycleEventService to LifecycleEventService) is repeated in both ConnectHandler and DisconnectHandler. Consider extracting this to a helper method or property to reduce code duplication and make the intent clearer. For example, a private method like TryGetLifecycleEventService() that returns the concrete service or null.
StephaneDelcroix
left a comment
There was a problem hiding this comment.
✅ APPROVE
Summary: PR correctly fixes BlazorWebView back navigation on Android 13+ by registering an OnBackPressed lifecycle event handler.
What the PR Does
- Adds
OnBackPressedhandler inConnectHandlerthat checksCanGoBack()before navigating - Handles multiple BlazorWebView instances with visibility/focus checks (
IsAttachedToWindow,HasWindowFocus) - Uses
WeakReferenceto prevent memory leaks - Adds
RemoveEventtoLifecycleEventServicefor proper cleanup - Cleans up handler in
DisconnectHandlerto prevent leaks
Tests Added
I've added Device Tests to verify the fix:
BlazorWebViewRegistersOnBackPressedHandler- Verifies handler is registered when BlazorWebView connectsBlazorWebViewCleansUpOnBackPressedHandlerOnDisconnect- Verifies cleanup on disconnect
Location: src/BlazorWebView/tests/DeviceTests/Elements/BlazorWebViewTests.BackNavigation.cs
Alternative Approaches Considered
- Override OnKeyDown: Won't work with Android 13+ predictive back gestures
- Use AndroidX OnBackPressedDispatcher directly: Bypasses MAUI's existing architecture
- PR's approach is optimal - integrates with MAUI's lifecycle event system
Minor Notes (Non-blocking)
RemoveEventkept internal (acceptable, would require API review for public)- Thread-safety matches existing pattern in
LifecycleEventService
Confidence: High - PR follows MAUI's established patterns and addresses all edge cases.
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run maui-pr-devicetests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
@StephaneDelcroix |
|
@SuthiYuvaraj Did you see my comment/videos in the linked issue at |
|
@PureWeen The issue where the back button immediately exited the app instead of navigating within the BlazorWebView is now fixed. |
|
I have tested the artifacts locally on my computer from @SubhikshaSf4851 's fix. |
|
/rebase |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Tests verify that BlazorWebViewHandler on Android: 1. Registers OnBackPressed lifecycle event handler in ConnectHandler 2. Properly cleans up the handler in DisconnectHandler Related to: dotnet#32767
5ade657 to
4714458
Compare
…dictive Back Gesture Changes (#33213) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Description BlazorWebView back navigation stopped working in .NET 10 on Android. When the user presses the back button while viewing a BlazorWebView with navigable history, the entire page is popped instead of navigating back within the WebView content ### RootCause The AndroidLifecycle.OnBackPressed lifecycle event system introduced for Android 13+ predictive back gesture support intercepts back navigation. Since BlazorWebView doesn't register a handler to check WebView.CanGoBack(), the system pops the entire page instead of allowing the WebView to navigate its internal history first, breaking the back navigation behavior that worked in .NET 9. ### Description of Change PR #32461 introduced distributed back navigation handling for Android 13+ predictive back gesture support. This PR extends that implementation to include BlazorWebView **BlazorWebViewHandler.Android.cs:** Added an `AndroidLifecycle.OnBackPressed` handler in ConnectHandler. The handler checks `WebView.CanGoBack()` to determine whether the BlazorWebView maintains internal navigation history. If history exists, it calls `WebView.GoBack()` and returns true, ensuring the user navigates backwards within the WebView instead of closing the page. If no internal history exists, it returns false, allowing the standard MAUI navigation stack to handle the back action. **LifecycleEventService.cs**: Added `RemoveEvent<TDelegate>` method to properly cleanup lifecycle event handlers and prevent memory leaks when handlers are disconnected. ### Issues Fixed Fixes #32767 ### Tested the behaviour on the following platforms - [x] Android - [ ] Windows - [ ] iOS - [ ] Mac ### Output Screenshot Before Issue Fix | After Issue Fix | |----------|----------| |<video width="300" height="150" alt="Before Fix" src="https://github.com/user-attachments/assets/0d6550f8-115a-4893-bb0c-ee24bff38378">|<video width="300" height="150" alt="After Fix" src="https://github.com/user-attachments/assets/49bf38a5-f7be-4790-8fbb-b29ab96b1ed3">| --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Subhiksha Chandrasekaran <subhiksha.c@syncfusion.com>
…dictive Back Gesture Changes (#33213) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Description BlazorWebView back navigation stopped working in .NET 10 on Android. When the user presses the back button while viewing a BlazorWebView with navigable history, the entire page is popped instead of navigating back within the WebView content ### RootCause The AndroidLifecycle.OnBackPressed lifecycle event system introduced for Android 13+ predictive back gesture support intercepts back navigation. Since BlazorWebView doesn't register a handler to check WebView.CanGoBack(), the system pops the entire page instead of allowing the WebView to navigate its internal history first, breaking the back navigation behavior that worked in .NET 9. ### Description of Change PR #32461 introduced distributed back navigation handling for Android 13+ predictive back gesture support. This PR extends that implementation to include BlazorWebView **BlazorWebViewHandler.Android.cs:** Added an `AndroidLifecycle.OnBackPressed` handler in ConnectHandler. The handler checks `WebView.CanGoBack()` to determine whether the BlazorWebView maintains internal navigation history. If history exists, it calls `WebView.GoBack()` and returns true, ensuring the user navigates backwards within the WebView instead of closing the page. If no internal history exists, it returns false, allowing the standard MAUI navigation stack to handle the back action. **LifecycleEventService.cs**: Added `RemoveEvent<TDelegate>` method to properly cleanup lifecycle event handlers and prevent memory leaks when handlers are disconnected. ### Issues Fixed Fixes #32767 ### Tested the behaviour on the following platforms - [x] Android - [ ] Windows - [ ] iOS - [ ] Mac ### Output Screenshot Before Issue Fix | After Issue Fix | |----------|----------| |<video width="300" height="150" alt="Before Fix" src="https://github.com/user-attachments/assets/0d6550f8-115a-4893-bb0c-ee24bff38378">|<video width="300" height="150" alt="After Fix" src="https://github.com/user-attachments/assets/49bf38a5-f7be-4790-8fbb-b29ab96b1ed3">| --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Subhiksha Chandrasekaran <subhiksha.c@syncfusion.com>
…dictive Back Gesture Changes (#33213) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Description BlazorWebView back navigation stopped working in .NET 10 on Android. When the user presses the back button while viewing a BlazorWebView with navigable history, the entire page is popped instead of navigating back within the WebView content ### RootCause The AndroidLifecycle.OnBackPressed lifecycle event system introduced for Android 13+ predictive back gesture support intercepts back navigation. Since BlazorWebView doesn't register a handler to check WebView.CanGoBack(), the system pops the entire page instead of allowing the WebView to navigate its internal history first, breaking the back navigation behavior that worked in .NET 9. ### Description of Change PR #32461 introduced distributed back navigation handling for Android 13+ predictive back gesture support. This PR extends that implementation to include BlazorWebView **BlazorWebViewHandler.Android.cs:** Added an `AndroidLifecycle.OnBackPressed` handler in ConnectHandler. The handler checks `WebView.CanGoBack()` to determine whether the BlazorWebView maintains internal navigation history. If history exists, it calls `WebView.GoBack()` and returns true, ensuring the user navigates backwards within the WebView instead of closing the page. If no internal history exists, it returns false, allowing the standard MAUI navigation stack to handle the back action. **LifecycleEventService.cs**: Added `RemoveEvent<TDelegate>` method to properly cleanup lifecycle event handlers and prevent memory leaks when handlers are disconnected. ### Issues Fixed Fixes #32767 ### Tested the behaviour on the following platforms - [x] Android - [ ] Windows - [ ] iOS - [ ] Mac ### Output Screenshot Before Issue Fix | After Issue Fix | |----------|----------| |<video width="300" height="150" alt="Before Fix" src="https://github.com/user-attachments/assets/0d6550f8-115a-4893-bb0c-ee24bff38378">|<video width="300" height="150" alt="After Fix" src="https://github.com/user-attachments/assets/49bf38a5-f7be-4790-8fbb-b29ab96b1ed3">| --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Subhiksha Chandrasekaran <subhiksha.c@syncfusion.com>
…dictive Back Gesture Changes (#33213) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Description BlazorWebView back navigation stopped working in .NET 10 on Android. When the user presses the back button while viewing a BlazorWebView with navigable history, the entire page is popped instead of navigating back within the WebView content ### RootCause The AndroidLifecycle.OnBackPressed lifecycle event system introduced for Android 13+ predictive back gesture support intercepts back navigation. Since BlazorWebView doesn't register a handler to check WebView.CanGoBack(), the system pops the entire page instead of allowing the WebView to navigate its internal history first, breaking the back navigation behavior that worked in .NET 9. ### Description of Change PR #32461 introduced distributed back navigation handling for Android 13+ predictive back gesture support. This PR extends that implementation to include BlazorWebView **BlazorWebViewHandler.Android.cs:** Added an `AndroidLifecycle.OnBackPressed` handler in ConnectHandler. The handler checks `WebView.CanGoBack()` to determine whether the BlazorWebView maintains internal navigation history. If history exists, it calls `WebView.GoBack()` and returns true, ensuring the user navigates backwards within the WebView instead of closing the page. If no internal history exists, it returns false, allowing the standard MAUI navigation stack to handle the back action. **LifecycleEventService.cs**: Added `RemoveEvent<TDelegate>` method to properly cleanup lifecycle event handlers and prevent memory leaks when handlers are disconnected. ### Issues Fixed Fixes #32767 ### Tested the behaviour on the following platforms - [x] Android - [ ] Windows - [ ] iOS - [ ] Mac ### Output Screenshot Before Issue Fix | After Issue Fix | |----------|----------| |<video width="300" height="150" alt="Before Fix" src="https://github.com/user-attachments/assets/0d6550f8-115a-4893-bb0c-ee24bff38378">|<video width="300" height="150" alt="After Fix" src="https://github.com/user-attachments/assets/49bf38a5-f7be-4790-8fbb-b29ab96b1ed3">| --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Subhiksha Chandrasekaran <subhiksha.c@syncfusion.com>
…dictive Back Gesture Changes (#33213) <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> ### Issue Description BlazorWebView back navigation stopped working in .NET 10 on Android. When the user presses the back button while viewing a BlazorWebView with navigable history, the entire page is popped instead of navigating back within the WebView content ### RootCause The AndroidLifecycle.OnBackPressed lifecycle event system introduced for Android 13+ predictive back gesture support intercepts back navigation. Since BlazorWebView doesn't register a handler to check WebView.CanGoBack(), the system pops the entire page instead of allowing the WebView to navigate its internal history first, breaking the back navigation behavior that worked in .NET 9. ### Description of Change PR #32461 introduced distributed back navigation handling for Android 13+ predictive back gesture support. This PR extends that implementation to include BlazorWebView **BlazorWebViewHandler.Android.cs:** Added an `AndroidLifecycle.OnBackPressed` handler in ConnectHandler. The handler checks `WebView.CanGoBack()` to determine whether the BlazorWebView maintains internal navigation history. If history exists, it calls `WebView.GoBack()` and returns true, ensuring the user navigates backwards within the WebView instead of closing the page. If no internal history exists, it returns false, allowing the standard MAUI navigation stack to handle the back action. **LifecycleEventService.cs**: Added `RemoveEvent<TDelegate>` method to properly cleanup lifecycle event handlers and prevent memory leaks when handlers are disconnected. ### Issues Fixed Fixes #32767 ### Tested the behaviour on the following platforms - [x] Android - [ ] Windows - [ ] iOS - [ ] Mac ### Output Screenshot Before Issue Fix | After Issue Fix | |----------|----------| |<video width="300" height="150" alt="Before Fix" src="https://github.com/user-attachments/assets/0d6550f8-115a-4893-bb0c-ee24bff38378">|<video width="300" height="150" alt="After Fix" src="https://github.com/user-attachments/assets/49bf38a5-f7be-4790-8fbb-b29ab96b1ed3">| --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Subhiksha Chandrasekaran <subhiksha.c@syncfusion.com>
Issue Description
BlazorWebView back navigation stopped working in .NET 10 on Android. When the user presses the back button while viewing a BlazorWebView with navigable history, the entire page is popped instead of navigating back within the WebView content
RootCause
The AndroidLifecycle.OnBackPressed lifecycle event system introduced for Android 13+ predictive back gesture support intercepts back navigation. Since BlazorWebView doesn't register a handler to check WebView.CanGoBack(), the system pops the entire page instead of allowing the WebView to navigate its internal history first, breaking the back navigation behavior that worked in .NET 9.
Description of Change
PR #32461 introduced distributed back navigation handling for Android 13+ predictive back gesture support. This PR extends that implementation to include BlazorWebView
BlazorWebViewHandler.Android.cs:
Added an
AndroidLifecycle.OnBackPressedhandler in ConnectHandler. The handler checksWebView.CanGoBack()to determine whether the BlazorWebView maintains internal navigation history. If history exists, it callsWebView.GoBack()and returns true, ensuring the user navigates backwards within the WebView instead of closing the page. If no internal history exists, it returns false, allowing the standard MAUI navigation stack to handle the back action.LifecycleEventService.cs:
Added
RemoveEvent<TDelegate>method to properly cleanup lifecycle event handlers and prevent memory leaks when handlers are disconnected.Issues Fixed
Fixes #32767
Tested the behaviour on the following platforms
Output Screenshot
Screen.Recording.2025-12-18.at.7.21.48.PM.mov
Screen.Recording.2025-12-18.at.7.13.08.PM.mov