diff options
author | E.Z. Hart <hartez@users.noreply.github.com> | 2017-04-13 09:11:50 -0600 |
---|---|---|
committer | Rui Marinho <me@ruimarinho.net> | 2017-04-13 16:11:50 +0100 |
commit | aa1811126570b7d5e10c0473bad3b0dd0fb858eb (patch) | |
tree | 5128450f920dc05e3dcd9fe42dba076444193f09 /Xamarin.Forms.Platform.Android/AppCompat | |
parent | a0affaafbd6d6721a5501384777959c7384d7ddb (diff) | |
download | xamarin-forms-aa1811126570b7d5e10c0473bad3b0dd0fb858eb.tar.gz xamarin-forms-aa1811126570b7d5e10c0473bad3b0dd0fb858eb.tar.bz2 xamarin-forms-aa1811126570b7d5e10c0473bad3b0dd0fb858eb.zip |
Verify FragmentContainer created when queueing fragment transaction (Android) (#865)
* Add check for disposed MasterDetailContainer when queueing fragment transaction
* Fix various ObjectDisposedExceptions when setting main page
* Add check for legacy renderers when querying control properties
Diffstat (limited to 'Xamarin.Forms.Platform.Android/AppCompat')
-rw-r--r-- | Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs | 15 | ||||
-rw-r--r-- | Xamarin.Forms.Platform.Android/AppCompat/Platform.cs | 20 |
2 files changed, 31 insertions, 4 deletions
diff --git a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs index 0265cd3d..50840926 100644 --- a/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs +++ b/Xamarin.Forms.Platform.Android/AppCompat/MasterDetailContainer.cs @@ -1,3 +1,4 @@ +using System; using Android.App; using Android.Content; using Android.OS; @@ -86,7 +87,7 @@ namespace Xamarin.Forms.Platform.Android.AppCompat // The renderers for NavigationPage and TabbedPage both host fragments, so they need to be wrapped in a // FragmentContainer in order to get isolated fragment management Fragment fragment = FragmentContainer.CreateInstance(page); - + var fc = fragment as FragmentContainer; fc?.SetOnCreateCallback(pc => @@ -112,7 +113,17 @@ namespace Xamarin.Forms.Platform.Android.AppCompat _currentFragment = fragment; - new Handler(Looper.MainLooper).PostAtFrontOfQueue(() => FragmentManager.ExecutePendingTransactions()); + new Handler(Looper.MainLooper).PostAtFrontOfQueue(() => + { + if (_pageContainer == null) + { + // The view we're hosting in the fragment was never created (possibly we're already + // navigating to another page?) so there's nothing to commit + return; + } + + FragmentManager.ExecutePendingTransactions(); + }); } } diff --git a/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs b/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs index 0416ae3a..872bac77 100644 --- a/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs +++ b/Xamarin.Forms.Platform.Android/AppCompat/Platform.cs @@ -3,10 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Android.Content; +using Android.OS; using Android.Views; using Android.Views.Animations; using ARelativeLayout = Android.Widget.RelativeLayout; using Xamarin.Forms.Internals; +using Debug = System.Diagnostics.Debug; namespace Xamarin.Forms.Platform.Android.AppCompat { @@ -219,12 +221,14 @@ namespace Xamarin.Forms.Platform.Android.AppCompat internal void SetPage(Page newRoot) { var layout = false; + List<IVisualElementRenderer> toDispose = null; + if (Page != null) { _renderer.RemoveAllViews(); - foreach (IVisualElementRenderer rootRenderer in _navModel.Roots.Select(Android.Platform.GetRenderer)) - rootRenderer.Dispose(); + toDispose = _navModel.Roots.Select(Android.Platform.GetRenderer).ToList(); + _navModel = new NavigationModel(); layout = true; @@ -240,6 +244,18 @@ namespace Xamarin.Forms.Platform.Android.AppCompat AddChild(Page, layout); Application.Current.NavigationProxy.Inner = this; + + if (toDispose?.Count > 0) + { + // Queue up disposal of the previous renderers after the current layout updates have finished + new Handler(Looper.MainLooper).Post(() => + { + foreach (IVisualElementRenderer rootRenderer in toDispose) + { + rootRenderer.Dispose(); + } + }); + } } void AddChild(Page page, bool layout = false) |