Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit 56e99c8

Browse files
kvptrmarinho
authored andcommitted
[Android] Fix various issues in object dispose methods. (#6467)
* Android - Fix various issues in object dispose methods. * Tear down old element before disposing the ItemViewAdapter. * More fixes. * NavigationPageRenderer - Reorder ResetToolbar and remove view before dispose ShellSectionRenderer - Call base.Destroy last + Remove and destroy _scrollview * Remove obsolete code. * Fix build.
1 parent bff4469 commit 56e99c8

18 files changed

+254
-182
lines changed

Xamarin.Forms.Platform.Android/AppCompat/CarouselPageRenderer.cs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Specialized;
33
using System.ComponentModel;
44
using Android.Content;
@@ -51,29 +51,38 @@ protected override void Dispose(bool disposing)
5151
if (disposing && !_disposed)
5252
{
5353
_disposed = true;
54-
RemoveAllViews();
55-
foreach (ContentPage pageToRemove in Element.Children)
56-
{
57-
IVisualElementRenderer pageRenderer = Android.Platform.GetRenderer(pageToRemove);
58-
if (pageRenderer != null)
59-
{
60-
pageRenderer.View.RemoveFromParent();
61-
pageRenderer.Dispose();
62-
}
63-
pageToRemove.ClearValue(Android.Platform.RendererProperty);
64-
}
54+
55+
if (Element != null)
56+
PageController.InternalChildren.CollectionChanged -= OnChildrenCollectionChanged;
6557

6658
if (_viewPager != null)
6759
{
60+
RemoveView(_viewPager);
61+
62+
_viewPager.ClearOnPageChangeListeners();
6863
_viewPager.Adapter.Dispose();
6964
_viewPager.Dispose();
7065
_viewPager = null;
7166
}
7267

73-
_previousPage = null;
68+
RemoveAllViews();
7469

75-
if (Element != null)
76-
PageController.InternalChildren.CollectionChanged -= OnChildrenCollectionChanged;
70+
_previousPage = null;
71+
72+
if (Element?.Children != null)
73+
{
74+
foreach (ContentPage pageToRemove in Element.Children)
75+
{
76+
IVisualElementRenderer pageRenderer = Android.Platform.GetRenderer(pageToRemove);
77+
if (pageRenderer != null)
78+
{
79+
pageRenderer.View.RemoveFromParent();
80+
pageRenderer.Dispose();
81+
}
82+
83+
pageToRemove.ClearValue(Android.Platform.RendererProperty);
84+
}
85+
}
7786
}
7887

7988
base.Dispose(disposing);

Xamarin.Forms.Platform.Android/AppCompat/FormsAppCompatActivity.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ protected override void OnDestroy()
211211

212212
PopupManager.Unsubscribe(this);
213213

214+
_layout.RemoveView(Platform);
215+
214216
Platform?.Dispose();
215217

216218
// call at the end to avoid race conditions with Platform dispose
@@ -227,6 +229,12 @@ protected override void OnPause()
227229
{
228230
_layout.HideKeyboard(true);
229231

232+
if (Forms.IsLollipopOrNewer)
233+
{
234+
// Don't listen for power save mode changes while we're paused
235+
UnregisterReceiver(_powerSaveModeBroadcastReceiver);
236+
}
237+
230238
// Stop animations or other ongoing actions that could consume CPU
231239
// Commit unsaved changes, build only if users expect such changes to be permanently saved when thy leave such as a draft email
232240
// Release system resources, such as broadcast receivers, handles to sensors (like GPS), or any resources that may affect battery life when your activity is paused.
@@ -236,12 +244,6 @@ protected override void OnPause()
236244
_previousState = _currentState;
237245
_currentState = AndroidApplicationLifecycleState.OnPause;
238246

239-
if (Forms.IsLollipopOrNewer)
240-
{
241-
// Don't listen for power save mode changes while we're paused
242-
UnregisterReceiver(_powerSaveModeBroadcastReceiver);
243-
}
244-
245247
OnStateChanged();
246248
}
247249

@@ -318,7 +320,7 @@ void AppOnPropertyChanged(object sender, PropertyChangedEventArgs args)
318320
}
319321

320322
if (args.PropertyName == nameof(_application.MainPage))
321-
InternalSetPage(_application.MainPage);
323+
SetMainPage();
322324
if (args.PropertyName == PlatformConfiguration.AndroidSpecific.Application.WindowSoftInputModeAdjustProperty.PropertyName)
323325
SetSoftInputMode();
324326
}

Xamarin.Forms.Platform.Android/AppCompat/ImageButtonRenderer.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ protected override void Dispose(bool disposing)
8383

8484
if (disposing)
8585
{
86+
if (Element != null)
87+
{
88+
Element.PropertyChanged -= OnElementPropertyChanged;
89+
}
90+
91+
SetOnClickListener(null);
92+
SetOnTouchListener(null);
93+
OnFocusChangeListener = null;
8694

8795
ImageElementManager.Dispose(this);
8896

@@ -94,11 +102,9 @@ protected override void Dispose(bool disposing)
94102

95103
if (Element != null)
96104
{
97-
Element.PropertyChanged -= OnElementPropertyChanged;
98-
99-
if (Android.Platform.GetRenderer(Element) == this)
105+
if (Platform.GetRenderer(Element) == this)
100106
{
101-
Element.ClearValue(Android.Platform.RendererProperty);
107+
Element.ClearValue(Platform.RendererProperty);
102108
}
103109

104110
Element = null;

Xamarin.Forms.Platform.Android/AppCompat/MasterDetailPageRenderer.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,22 @@ protected override void Dispose(bool disposing)
214214

215215
if (disposing)
216216
{
217+
Device.Info.PropertyChanged -= DeviceInfoPropertyChanged;
218+
219+
if (Element != null)
220+
{
221+
MasterDetailPageController.BackButtonPressed -= OnBackButtonPressed;
222+
Element.PropertyChanged -= HandlePropertyChanged;
223+
Element.Appearing -= MasterDetailPageAppearing;
224+
Element.Disappearing -= MasterDetailPageDisappearing;
225+
}
226+
227+
if (_masterLayout?.ChildView != null)
228+
_masterLayout.ChildView.PropertyChanged -= HandleMasterPropertyChanged;
229+
230+
if (!this.IsDisposed())
231+
RemoveDrawerListener(this);
232+
217233
if (_tracker != null)
218234
{
219235
_tracker.Dispose();
@@ -229,26 +245,13 @@ protected override void Dispose(bool disposing)
229245

230246
if (_masterLayout != null)
231247
{
232-
if (_masterLayout.ChildView != null)
233-
_masterLayout.ChildView.PropertyChanged -= HandleMasterPropertyChanged;
234-
235248
RemoveView(_masterLayout);
236249
_masterLayout.Dispose();
237250
_masterLayout = null;
238251
}
239252

240-
Device.Info.PropertyChanged -= DeviceInfoPropertyChanged;
241-
242-
if (!this.IsDisposed())
243-
RemoveDrawerListener(this);
244-
245253
if (Element != null)
246254
{
247-
MasterDetailPageController.BackButtonPressed -= OnBackButtonPressed;
248-
Element.PropertyChanged -= HandlePropertyChanged;
249-
Element.Appearing -= MasterDetailPageAppearing;
250-
Element.Disappearing -= MasterDetailPageDisappearing;
251-
252255
Element.ClearValue(Android.Platform.RendererProperty);
253256
Element = null;
254257
}

Xamarin.Forms.Platform.Android/AppCompat/NavigationPageRenderer.cs

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -170,17 +170,46 @@ protected override void Dispose(bool disposing)
170170

171171
if (disposing)
172172
{
173-
if (_titleViewRenderer != null)
173+
Device.Info.PropertyChanged -= DeviceInfoPropertyChanged;
174+
175+
if (NavigationPageController != null)
174176
{
175-
Android.Platform.ClearRenderer(_titleViewRenderer.View);
176-
_titleViewRenderer.Dispose();
177-
_titleViewRenderer = null;
177+
var navController = NavigationPageController;
178+
179+
navController.PushRequested -= OnPushed;
180+
navController.PopRequested -= OnPopped;
181+
navController.PopToRootRequested -= OnPoppedToRoot;
182+
navController.InsertPageBeforeRequested -= OnInsertPageBeforeRequested;
183+
navController.RemovePageRequested -= OnRemovePageRequested;
184+
}
185+
186+
if (Current != null)
187+
{
188+
Current.PropertyChanged -= CurrentOnPropertyChanged;
178189
}
179190

191+
FragmentManager fm = FragmentManager;
192+
193+
if (!fm.IsDestroyed)
194+
{
195+
FragmentTransaction trans = fm.BeginTransactionEx();
196+
foreach (Fragment fragment in _fragmentStack)
197+
trans.RemoveEx(fragment);
198+
trans.CommitAllowingStateLossEx();
199+
fm.ExecutePendingTransactionsEx();
200+
}
201+
180202
_toolbar.RemoveView(_titleView);
181203
_titleView?.Dispose();
182204
_titleView = null;
183205

206+
if (_titleViewRenderer != null)
207+
{
208+
Android.Platform.ClearRenderer(_titleViewRenderer.View);
209+
_titleViewRenderer.Dispose();
210+
_titleViewRenderer = null;
211+
}
212+
184213
_toolbar.RemoveView(_titleIconView);
185214
_titleIconView?.Dispose();
186215
_titleIconView = null;
@@ -190,20 +219,30 @@ protected override void Dispose(bool disposing)
190219
if (_toolbarTracker != null)
191220
{
192221
_toolbarTracker.CollectionChanged -= ToolbarTrackerOnCollectionChanged;
222+
223+
foreach (ToolbarItem item in _toolbarTracker.ToolbarItems)
224+
item.PropertyChanged -= OnToolbarItemPropertyChanged;
225+
193226
_toolbarTracker.Target = null;
194227
_toolbarTracker = null;
195228
}
196229

197230
if (_toolbar != null)
198231
{
199232
_toolbar.SetNavigationOnClickListener(null);
233+
_toolbar.Menu.Clear();
234+
235+
RemoveView(_toolbar);
236+
200237
_toolbar.Dispose();
201238
_toolbar = null;
202239
}
203240

204241
if (_drawerLayout.IsAlive() && _drawerListener.IsAlive())
205242
{
206243
_drawerLayout.RemoveDrawerListener(_drawerListener);
244+
245+
RemoveView(_drawerLayout);
207246
}
208247

209248
if (_drawerListener != null)
@@ -239,31 +278,6 @@ protected override void Dispose(bool disposing)
239278
IVisualElementRenderer renderer = Android.Platform.GetRenderer(child);
240279
renderer?.Dispose();
241280
}
242-
243-
var navController = NavigationPageController;
244-
245-
navController.PushRequested -= OnPushed;
246-
navController.PopRequested -= OnPopped;
247-
navController.PopToRootRequested -= OnPoppedToRoot;
248-
navController.InsertPageBeforeRequested -= OnInsertPageBeforeRequested;
249-
navController.RemovePageRequested -= OnRemovePageRequested;
250-
}
251-
252-
Device.Info.PropertyChanged -= DeviceInfoPropertyChanged;
253-
254-
// API only exists on newer android YAY
255-
if ((int)Build.VERSION.SdkInt >= 17)
256-
{
257-
FragmentManager fm = FragmentManager;
258-
259-
if (!fm.IsDestroyed)
260-
{
261-
FragmentTransaction trans = fm.BeginTransactionEx();
262-
foreach (Fragment fragment in _fragmentStack)
263-
trans.RemoveEx(fragment);
264-
trans.CommitAllowingStateLossEx();
265-
fm.ExecutePendingTransactionsEx();
266-
}
267281
}
268282
}
269283

@@ -313,8 +327,6 @@ protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage>
313327
oldNavController.RemovePageRequested -= OnRemovePageRequested;
314328

315329
RemoveAllViews();
316-
if (_toolbar != null)
317-
AddView(_toolbar);
318330
}
319331

320332
if (e.NewElement != null)
@@ -714,22 +726,24 @@ void ResetToolbar()
714726
{
715727
AToolbar oldToolbar = _toolbar;
716728

729+
_toolbar.SetNavigationOnClickListener(null);
730+
_toolbar.RemoveFromParent();
731+
732+
_toolbar.RemoveView(_titleView);
733+
_titleView = null;
734+
717735
if (_titleViewRenderer != null)
718736
{
719737
Android.Platform.ClearRenderer(_titleViewRenderer.View);
738+
_titleViewRenderer.Dispose();
720739
_titleViewRenderer = null;
721740
}
722741

723-
_toolbar.RemoveView(_titleView);
724-
_titleView = null;
725-
726742
_toolbar.RemoveView(_titleIconView);
727743
_titleIconView = null;
728744

729745
_imageSource = null;
730746

731-
_toolbar.RemoveFromParent();
732-
_toolbar.SetNavigationOnClickListener(null);
733747
_toolbar = null;
734748

735749
SetupToolbar();

0 commit comments

Comments
 (0)