Koji
Koji

Reputation: 588

When are .NET MAUI (Xamarin Forms) pages/custom views destroyed?

I'm new to Xamarin/.NET MAUI application development. I started to develop a sample .NET MAUI application for Android device.
I'm trying to understand how/when a page and my custom view are destroyed (disposed of). I read some web pages but I can't really understand how things work in .NET MAUI (or Xamarin).

I have three pages: MainPage, SecondPage, TestMapPage.
SecondPage has a button that navigates to TestMapPage. It instantiates a TestMapPage object and passes it to Navigation.PushAsync().
TestMapPage contains a custom view TestMapView, which is rendered by my custom view renderer TestMapViewRenderer. I create a MapView object (from Naxam.Mapbox.Droid) in the renderer and show the map in TestMapPage. The map appears on the emulator and it works fine.

I thought that SecondPage, TestMapPage and TestMapView (and all the objects in TestMapViewRenderer) will be destroyed when I navigate back to MainPage. However, when I set a break point on Dispose() in the renderer and navigate back to SecondPage or MainPage in , it never gets hit.

My questions:

  1. Are the SecondPage, TestMapPage, TestMapView and all the other objects in the view and view renderer like MapboxMap kept somewhere when I go back to MainPage?
  2. When are pages and views destroyed/disposed of?
  3. If those page objects are kept somewhere until the application shuts down, is it normal behaviour?
  4. If not normal behaviour, how do I fix it?

I'm worried about memory leak...

MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    // ...
    private async void OnGoToSecondPageClicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync(new SecondPage());
    }
}

SecondPage.xaml.cs

public partial class SecondPage : ContentPage
{
    // ...
    private async void OnMapShowClicked(object sender, EventArgs e)
    {
        await Navigation.PushAsync(new TestMapPage());
    }
}

TestMapPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MapTest"
             x:Class="MapTest.TestMapPage">
    <StackLayout Margin="5">
        <local:TestMapView
            x:Name="map"
            VerticalOptions="FillAndExpand" 
            HorizontalOptions="CenterAndExpand"/>
    </StackLayout>
</ContentPage>

TestMapView.cs

public class TestMapView : View { }

TestMapViewRenderer.cs

public partial class TestMapViewRenderer : ViewRenderer<TestMapView, Android.Views.View>
{
    private MapboxMap map;

    public TestMapViewRenderer(Context context) : base(context) {}

    protected override void OnElementChanged(ElementChangedEventArgs<TestMapView> e)
    {
        base.OnElementChanged(e);
        // ...
        if (Control == null)
        {
            var mapView = new MapView(Context);
            SetNativeControl(mapView);
            mapView.GetMapAsync(this);
        }
    }

    public void OnMapReady(MapboxMap map)
    {
        this.map = map;
        this.map.SetStyle(Resources.GetString(Resource.String.mapbox_style_satellite), this);
    }

    protected override void Dispose(bool disposing)
    {
        // A breakpoint never hits on this line. Why?
        base.Dispose(disposing);
    }
    // ...
}

Upvotes: 3

Views: 2339

Answers (1)

Sebastian Busek
Sebastian Busek

Reputation: 1032

as far as I know;

  1. No, on each navigation you create new page instances, so, the page is created and kept in memory by .NET itself, once garbage collection hits a certain threshold, the memory will be free. Until then, the pages are in memory, but not meant to use somewhen in the future.
  2. When GC decides, the Xamarin/MAUI doesn't care about views.
  3. Unfortunately, yes.
  4. It's normal, you can overcome by using what @ToolmakerSteve refers.

Upvotes: 0

Related Questions