Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
6 changes: 6 additions & 0 deletions src/Controls/src/Core/Application/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,12 @@ IWindow IApplication.CreateWindow(IActivationState? activationState)
}
}

// On Android, reuse existing window when Activity is recreated due to lifecycle changes
#if ANDROID
if (window == null && _windows.Count > 0)
window = _windows[0];
#endif

// create a new one if there is no pending windows
if (window == null)
{
Expand Down
11 changes: 8 additions & 3 deletions src/Controls/src/Core/Window/Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -544,13 +544,18 @@ void IWindow.Destroying()
OnDestroying();

AlertManager.Unsubscribe();
Application?.RemoveWindow(this);

// On Android, preserve window in collection to enable reuse when Activity is recreated
#if !ANDROID
Application?.RemoveWindow(this);
#endif

var mauiContext = Handler?.MauiContext as MauiContext;
Handler?.DisconnectHandler();

// Dispose the window-scoped service scope
// On Android, preserve window scope to enable reuse when Activity is recreated
#if !ANDROID
mauiContext?.DisposeWindowScope();
#endif
}

void IWindow.Resumed()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Maui.Controls;
using Microsoft.Maui.DeviceTests.Stubs;
using Xunit;

namespace Microsoft.Maui.DeviceTests
{
public partial class WindowTests
{
[Fact]
public async Task WindowDestroyingPreservesWindowScopeOnAndroid()
{
// https://github.com/dotnet/maui/issues/33597
SetupBuilder();

var window = new Window(new ContentPage());

await CreateHandlerAndAddToWindow<WindowHandlerStub>(window, async handler =>
{
await OnLoadedAsync(window.Page);

var mauiContext = handler.MauiContext as MauiContext;
Assert.NotNull(mauiContext);

var windowScopeField = typeof(MauiContext).GetField("_windowScope", BindingFlags.NonPublic | BindingFlags.Instance);
var setWindowScope = typeof(MauiContext).GetMethod("SetWindowScope", BindingFlags.NonPublic | BindingFlags.Instance);

var newScope = mauiContext.Services.CreateScope();
setWindowScope.Invoke(mauiContext, new[] { newScope });
Assert.NotNull(windowScopeField.GetValue(mauiContext));

((IWindow)window).Destroying();

Assert.NotNull(windowScopeField.GetValue(mauiContext));
});
}

[Fact]
public async Task WindowDestroyingPreservesWindowCollectionOnAndroid()
{
// https://github.com/dotnet/maui/issues/33597
SetupBuilder();

var app = Application.Current;
var window = new Window(new ContentPage());

await CreateHandlerAndAddToWindow<WindowHandlerStub>(window, async handler =>
{
await OnLoadedAsync(window.Page);

window.Parent = app;

var windowsField = typeof(Application).GetField("_windows", BindingFlags.NonPublic | BindingFlags.Instance);
var windowsList = windowsField.GetValue(app) as IList<Window>;

if (!windowsList.Contains(window))
windowsList.Add(window);

var countBefore = windowsList.Count;

((IWindow)window).Destroying();

Assert.Equal(countBefore, windowsList.Count);
Assert.Contains(window, windowsList);
});
}
}
}
Loading