@@ -27,6 +27,21 @@ public partial class BlazorWebViewHandler : ViewHandler<IBlazorWebView, AWebView
2727 private ILogger ? _logger ;
2828 internal ILogger Logger => _logger ??= Services ! . GetService < ILogger < BlazorWebViewHandler > > ( ) ?? NullLogger < BlazorWebViewHandler > . Instance ;
2929
30+ /// <summary>
31+ /// Gets the concrete LifecycleEventService to access internal RemoveEvent method.
32+ /// RemoveEvent is internal because it's not part of the public ILifecycleEventService contract,
33+ /// but is needed for proper cleanup of lifecycle event handlers.
34+ /// </summary>
35+ private LifecycleEventService ? TryGetLifecycleEventService ( )
36+ {
37+ var services = MauiContext ? . Services ;
38+ if ( services != null )
39+ {
40+ return services . GetService < ILifecycleEventService > ( ) as LifecycleEventService ;
41+ }
42+ return null ;
43+ }
44+
3045 protected override AWebView CreatePlatformView ( )
3146 {
3247 Logger . CreatingAndroidWebkitWebView ( ) ;
@@ -62,22 +77,44 @@ protected override AWebView CreatePlatformView()
6277 return blazorAndroidWebView ;
6378 }
6479
80+ /// <summary>
81+ /// Connects the handler to the Android <see cref="AWebView"/> and registers platform-specific
82+ /// back navigation handling so that the WebView can consume back presses before the page is popped.
83+ /// </summary>
84+ /// <param name="platformView">The native Android <see cref="AWebView"/> instance associated with this handler.</param>
85+ /// <remarks>
86+ /// This override calls the base implementation and then registers an <see cref="AndroidLifecycle.OnBackPressed"/>
87+ /// lifecycle event handler. The handler checks <see cref="AWebView.CanGoBack"/> and, when possible, navigates
88+ /// back within the WebView instead of allowing the back press (or predictive back gesture on Android 13+)
89+ /// to propagate and pop the containing page.
90+ /// <para>
91+ /// When multiple BlazorWebView instances exist, the handler includes focus and visibility checks to ensure
92+ /// only the currently visible and focused WebView handles the back navigation, preventing conflicts between instances.
93+ /// </para>
94+ /// Inheritors that override this method should call the base implementation to preserve this back navigation
95+ /// behavior unless they intentionally replace it.
96+ /// </remarks>
6597 protected override void ConnectHandler ( AWebView platformView )
6698 {
6799 base . ConnectHandler ( platformView ) ;
68100
69101 // Register OnBackPressed lifecycle event handler to check WebView's back navigation
70102 // This ensures predictive back gesture (Android 13+) checks WebView.CanGoBack() before popping page
71- var services = MauiContext ? . Services ;
72- if ( services != null )
103+ var lifecycleService = TryGetLifecycleEventService ( ) ;
104+ if ( lifecycleService != null )
73105 {
74106 // Create a weak reference to avoid memory leaks
75107 var weakPlatformView = new WeakReference < AWebView > ( platformView ) ;
76108
77109 AndroidLifecycle . OnBackPressed handler = ( activity ) =>
78110 {
79- // Check if WebView is still alive and can navigate back
80- if ( weakPlatformView . TryGetTarget ( out var webView ) && webView . CanGoBack ( ) )
111+ // Check if WebView is still alive, attached to window, and has focus
112+ // This prevents non-visible or unfocused BlazorWebView instances from
113+ // incorrectly intercepting back navigation when multiple instances exist
114+ if ( weakPlatformView . TryGetTarget ( out var webView ) &&
115+ webView . IsAttachedToWindow &&
116+ webView . HasWindowFocus &&
117+ webView . CanGoBack ( ) )
81118 {
82119 webView . GoBack ( ) ;
83120 return true ; // Prevent back propagation - handled by WebView
@@ -87,12 +124,8 @@ protected override void ConnectHandler(AWebView platformView)
87124 } ;
88125
89126 // Register with lifecycle service - will be invoked by HandleBackNavigation in MauiAppCompatActivity
90- var lifecycleService = services . GetService < ILifecycleEventService > ( ) ;
91- if ( lifecycleService is LifecycleEventService concreteService )
92- {
93- concreteService . AddEvent ( nameof ( AndroidLifecycle . OnBackPressed ) , handler ) ;
94- _onBackPressedHandler = handler ;
95- }
127+ lifecycleService . AddEvent ( nameof ( AndroidLifecycle . OnBackPressed ) , handler ) ;
128+ _onBackPressedHandler = handler ;
96129 }
97130 }
98131
@@ -101,12 +134,12 @@ protected override void ConnectHandler(AWebView platformView)
101134 protected override void DisconnectHandler ( AWebView platformView )
102135 {
103136 // Clean up lifecycle event handler to prevent memory leaks
104- if ( _onBackPressedHandler != null && MauiContext ? . Services != null )
137+ if ( _onBackPressedHandler != null )
105138 {
106- var lifecycleService = MauiContext . Services . GetService < ILifecycleEventService > ( ) ;
107- if ( lifecycleService is LifecycleEventService concreteService )
139+ var lifecycleService = TryGetLifecycleEventService ( ) ;
140+ if ( lifecycleService != null )
108141 {
109- concreteService . RemoveEvent ( nameof ( AndroidLifecycle . OnBackPressed ) , _onBackPressedHandler ) ;
142+ lifecycleService . RemoveEvent ( nameof ( AndroidLifecycle . OnBackPressed ) , _onBackPressedHandler ) ;
110143 _onBackPressedHandler = null ;
111144 }
112145 }
0 commit comments