Skip to content

Commit 14d7d07

Browse files
SuthiYuvarajPureWeen
authored andcommitted
Update BlazorWebViewHandler.Android.cs
1 parent 90917be commit 14d7d07

File tree

1 file changed

+47
-14
lines changed

1 file changed

+47
-14
lines changed

src/BlazorWebView/src/Maui/Android/BlazorWebViewHandler.Android.cs

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)