Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/Core/src/Handlers/WebView/WebViewHandler.Android.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Net;
using Android.Views;
using Android.Webkit;
using static Android.Views.ViewGroup;
using AWebView = Android.Webkit.WebView;
Expand Down Expand Up @@ -63,12 +64,15 @@ protected override void DisconnectHandler(AWebView platformView)
webChromeClient.Disconnect();
}

platformView.SetWebViewClient(null!);
platformView.SetWebChromeClient(null);

platformView.StopLoading();
if (platformView.Parent is ViewGroup parent)
parent.RemoveView(platformView);
platformView.RemoveAllViews();

base.DisconnectHandler(platformView);
platformView.Destroy();
}

public static void MapSource(IWebViewHandler handler, IWebView webView)
Expand Down Expand Up @@ -331,4 +335,4 @@ void InitialCookiePreloadIfNecessary(string url)
return null;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Android.Content;
using Android.Views;
using Android.Webkit;
using Android.Widget;
using Microsoft.Maui.DeviceTests.Stubs;
using Microsoft.Maui.Platform;
using Xunit;
using AWebView = Android.Webkit.WebView;

Expand All @@ -15,5 +19,62 @@ AWebView GetNativeWebView(WebViewHandler webViewHandler) =>

string GetNativeSource(WebViewHandler webViewHandler) =>
GetNativeWebView(webViewHandler).Url;

[Fact(DisplayName = "DisconnectHandler Destroys Native WebView")]
public async Task DisconnectHandlerDestroysNativeWebView()
{
var originalFactory = WebViewHandler.PlatformViewFactory;

try
{
await InvokeOnMainThreadAsync(() =>
{
DestroyTrackingMauiWebView platformView = null;

WebViewHandler.PlatformViewFactory = handler =>
{
platformView = new DestroyTrackingMauiWebView((WebViewHandler)handler, handler.MauiContext!.Context!);
return platformView;
};

var webView = new WebViewStub();
var handler = CreateHandler(webView);
var parent = new FrameLayout(handler.MauiContext!.Context!);
parent.AddView(handler.PlatformView);

Assert.Same(parent, handler.PlatformView.Parent);

((IElementHandler)handler).DisconnectHandler();

var destroyTrackingWebView = platformView ?? throw new InvalidOperationException("Expected the WebView factory to create a platform view.");
Assert.True(destroyTrackingWebView.DestroyCalled);
Assert.Null(destroyTrackingWebView.ParentWhenDestroyed);
Assert.Equal(0, parent.ChildCount);
});
}
finally
{
WebViewHandler.PlatformViewFactory = originalFactory;
}
}

class DestroyTrackingMauiWebView : MauiWebView
{
public DestroyTrackingMauiWebView(WebViewHandler handler, Context context)
: base(handler, context)
{
}

public bool DestroyCalled { get; private set; }

public IViewParent ParentWhenDestroyed { get; private set; }

public override void Destroy()
{
DestroyCalled = true;
ParentWhenDestroyed = Parent;
base.Destroy();
}
}
}
}
Loading