This repository has been archived by the owner on May 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Android] Fix content pages not Garbage collected (#14717)
* Create test to prove that navigated-from content pages are not garbage collected when using Shell issue #14657 * Fix disposing Shell objects removing drawer listener (_drawerToggle) allows shell pages to be collected by GC issue #14657 * Correctly dispose views Shell TitleView is explicitly set to null, because otherwise pages would not be disposed of. Also views are explicitly removed during disposal. issue #14657
- Loading branch information
1 parent
e95006e
commit d59f34f
Showing
5 changed files
with
154 additions
and
1 deletion.
There are no files selected for viewing
136 changes: 136 additions & 0 deletions
136
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Issue14657.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
using Xamarin.Forms.CustomAttributes; | ||
using Xamarin.Forms.Internals; | ||
using System; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
|
||
#if UITEST | ||
using Xamarin.Forms.Core.UITests; | ||
using Xamarin.UITest; | ||
using NUnit.Framework; | ||
#endif | ||
|
||
namespace Xamarin.Forms.Controls.Issues | ||
{ | ||
#if UITEST | ||
[Category(UITestCategories.Github10000)] | ||
[Category(UITestCategories.Shell)] | ||
[Category(UITestCategories.TitleView)] | ||
#endif | ||
[Preserve(AllMembers = true)] | ||
[Issue(IssueTracker.Github, 14657, "Shell pages are not released from memory", PlatformAffected.Android)] | ||
public class Issue14657 : TestShell | ||
{ | ||
static int pageCount = 0; | ||
protected override void Init() | ||
{ | ||
Routing.RegisterRoute(nameof(Issue14657_ChildPage), typeof(Issue14657_ChildPage)); | ||
|
||
var rootPage = CreateRootPage(); | ||
|
||
AddContentPage(rootPage); | ||
} | ||
|
||
ContentPage CreateRootPage() | ||
{ | ||
var rootPage = CreateContentPage("Home page"); | ||
rootPage.Content = new StackLayout() | ||
{ | ||
Children = | ||
{ | ||
new Button() | ||
{ | ||
Command = new Command(CollectMemory), | ||
Text = "Force GC", | ||
AutomationId = "GC_14657" | ||
}, | ||
new Button() | ||
{ | ||
Command = new Command(async () => await GoToChild()), | ||
Text = "Go to child page", | ||
AutomationId = "GoToChild_14657" | ||
} | ||
} | ||
}; | ||
Shell.SetTitleView(rootPage, new StackLayout() | ||
{ | ||
Orientation = StackOrientation.Horizontal, | ||
Children = { new Label { Text = "Root Page" } } | ||
}); | ||
|
||
return rootPage; | ||
} | ||
|
||
public class Issue14657_ChildPage : ContentPage | ||
{ | ||
public Issue14657_ChildPage() | ||
{ | ||
Interlocked.Increment(ref pageCount); | ||
|
||
Content = new StackLayout | ||
{ | ||
Children = | ||
{ | ||
new Label() | ||
{ | ||
Text = $"{pageCount}", | ||
AutomationId = "CountLabel", | ||
TextColor = Color.Black | ||
}, | ||
new Button() | ||
{ | ||
Command = new Command(CollectMemory), | ||
Text = "Force GC", | ||
AutomationId = "GC_14657" | ||
} | ||
} | ||
}; | ||
} | ||
|
||
~Issue14657_ChildPage() | ||
{ | ||
Interlocked.Decrement(ref pageCount); | ||
} | ||
} | ||
|
||
async Task GoToChild() | ||
{ | ||
await GoToAsync(nameof(Issue14657_ChildPage)); | ||
} | ||
|
||
static void CollectMemory() | ||
{ | ||
GC.Collect(); | ||
GC.WaitForPendingFinalizers(); | ||
GC.WaitForPendingFinalizers(); | ||
GC.Collect(); | ||
GC.WaitForPendingFinalizers(); | ||
GC.WaitForPendingFinalizers(); | ||
GC.Collect(); | ||
} | ||
|
||
#if UITEST | ||
[Test] | ||
public void Issue14657Test() | ||
{ | ||
RunningApp.Tap("GoToChild_14657"); | ||
RunningApp.WaitForFirstElement("CountLabel") | ||
.AssertHasText("1"); | ||
RunningApp.NavigateBack(); | ||
RunningApp.Tap("GC_14657"); | ||
|
||
RunningApp.Tap("GoToChild_14657"); | ||
RunningApp.WaitForFirstElement("CountLabel") | ||
.AssertHasText("1"); | ||
RunningApp.NavigateBack(); | ||
RunningApp.Tap("GC_14657"); | ||
|
||
RunningApp.Tap("GoToChild_14657"); | ||
RunningApp.WaitForFirstElement("CountLabel") | ||
.AssertHasText("1"); | ||
RunningApp.NavigateBack(); | ||
} | ||
|
||
#endif | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters