[Android] Fix NullPointerException following RemovePage call (#933)

* Add repro for 53179

* Update Android packages to 25+

* Turn off linker to debug

* [Android] Only remove PageContainer < API 25

* Revert "Update Android packages to 25+"

This reverts commit ece252261d709213ad3a3c02c5fd37556bdb093f.

* Revert "Turn off linker to debug"

This reverts commit fdffff71386f1a4b186b89b7421d875e696b7bc7.

* Update test automation

* Add explanatory comment

* Fix test case number
This commit is contained in:
Samantha Houts 2017-06-14 06:40:03 -07:00 коммит произвёл Rui Marinho
Родитель 28a878d14f
Коммит d6252627d0
3 изменённых файлов: 101 добавлений и 9 удалений

Просмотреть файл

@ -0,0 +1,83 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Bugzilla, 53179, "PopAsync crashing after RemovePage when support packages are updated to 25.1.1", PlatformAffected.Android)]
public class Bugzilla53179 : TestNavigationPage
{
class TestPage : ContentPage
{
Button nextBtn, rmBtn, popBtn;
public TestPage(int index)
{
nextBtn = new Button { Text = "Next Page" };
rmBtn = new Button { Text = "Remove previous page" };
popBtn = new Button { Text = "Back" };
nextBtn.Clicked += async (sender, e) => await Navigation.PushAsync(new TestPage(index + 1));
rmBtn.Clicked += (sender, e) =>
{
var stackSize = Navigation.NavigationStack.Count;
Navigation.RemovePage(Navigation.NavigationStack[stackSize - 2]);
popBtn.IsVisible = true;
rmBtn.IsVisible = false;
};
popBtn.Clicked += async (sender, e) => await Navigation.PopAsync();
switch (index)
{
case 3:
nextBtn.IsVisible = false;
popBtn.IsVisible = false;
break;
default:
rmBtn.IsVisible = false;
popBtn.IsVisible = false;
break;
}
Content = new StackLayout
{
Children = {
new Label { Text = $"This is page {index}"},
nextBtn,
rmBtn,
popBtn
}
};
}
}
protected override void Init()
{
PushAsync(new TestPage(1));
}
#if UITEST
[Test]
public void Bugzilla53179Test()
{
RunningApp.WaitForElement(q => q.Marked("Next Page"));
RunningApp.Tap(q => q.Marked("Next Page"));
RunningApp.WaitForElement(q => q.Marked("Next Page"));
RunningApp.Tap(q => q.Marked("Next Page"));
RunningApp.WaitForElement(q => q.Marked("Remove previous page"));
RunningApp.Tap(q => q.Marked("Remove previous page"));
RunningApp.WaitForElement(q => q.Marked("Back"));
RunningApp.Tap(q => q.Marked("Back"));
}
#endif
}
}

Просмотреть файл

@ -289,6 +289,7 @@
<Compile Include="$(MSBuildThisFileDirectory)ListViewNRE.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla55745.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla55365.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla53179.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla54036.cs" />
<Compile Include="$(MSBuildThisFileDirectory)_Template.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue1028.cs" />

Просмотреть файл

@ -534,19 +534,27 @@ namespace Xamarin.Forms.Platform.Android.AppCompat
void RemovePage(Page page)
{
IVisualElementRenderer rendererToRemove = Android.Platform.GetRenderer(page);
var containerToRemove = (PageContainer)rendererToRemove?.View.Parent;
if (rendererToRemove != null)
{
var containerToRemove = (PageContainer)rendererToRemove.View.Parent;
rendererToRemove.View?.RemoveFromParent();
rendererToRemove?.Dispose();
// This causes a NullPointerException in API 25.1+ when we later call ExecutePendingTransactions();
// We may want to remove this in the future if it is resolved in the Android SDK.
if ((int)Build.VERSION.SdkInt < 25)
{
containerToRemove?.RemoveFromParent();
containerToRemove?.Dispose();
}
}
// Also remove this page from the fragmentStack
FilterPageFragment(page);
containerToRemove.RemoveFromParent();
if (rendererToRemove != null)
{
rendererToRemove.View.RemoveFromParent();
rendererToRemove.Dispose();
}
containerToRemove?.Dispose();
Device.StartTimer(TimeSpan.FromMilliseconds(10), () =>
{
UpdateToolbar();