Home > Net >  Which LifeCycleEvents to use in .NET MAUI on Android?
Which LifeCycleEvents to use in .NET MAUI on Android?

Time:11-28

I have a View (with ViewModel, both Singleton) that reads and writes to a text file. I would like it to be opened and closed in a controlled manner and am trying to work out where this should happen in the Maui app lifecycle.

In normal operation I assume that I should open it in OnAppearing and close in OnDisappearing.

If however the app is moved into the background and killed, OnDisappearing for the View does not fire.

It does fire OnPause, so I could close the file here and reopen it OnResume but would rather not use these for simplicity (although I will if recommended).

My questions are: Is there any event that fires when the app is killed by the user (i.e. put in background and swiped away). If the app is killed, will my text file be tidily flushed and closed? Does anyone have any recommendations for better ways to do this. I am new to MAUI and may be missing something fundamental.

CodePudding user response:

" Is there any event that fires when the app is killed by the user?"

No. Your app code does not get a chance to run at that time.

As you've discovered, there is a bit of a disconnect between App lifecycle (e.g Deactivated or OnPaused) and Page lifecycle (Appearing/Disappearing).

This is fundamental to Android itself, whether usng Maui or not. On Android, the only event that is guaranteed to happen before an app disappears is OnPaused; Maui app's Deactivated event runs when Android activity's OnPaused is called.

Unfortunately after OnPaused, its possible that your app will not get to run any other code later. You'll have to design everythng with that in mind.

Regardless of what page or popup your app is showing, or what it is in the middle of, your "app Deactivated" code is responsible for saving whatever information needs to be persisted.

Below follows one conceptual way to handle the situation.


"If the app is killed, will my text file be tidily flushed and closed?"

No. Unfortunately, there is no standard mechanism that does this for you.
The burden is on you to keep track of what "clean-up" is needed, depending on what user has done / is doing in app.

Consider defining public class BasePage : ContentPage class, that has some methods that manage this. Have your pages inherit from BasePage.

An example:

// In App.xaml.cs:
protected override void OnDeactivated()
{
  CurrentPage?.SaveData();
  ...
}


private static BasePage CurrentPage;
public static void PageAppearing(BasePage page)
{
  CurrentPage = page;
}
public static void PageDisappearing(BasePage page)
{
  // Null CurrentPage, but skip that if has already changed to a different page.
  // (Fixes a bug on some XForms implementations; haven't tested whether this is still an issue in Maui.)
  if (ReferenceEquals(CurrentPage, page)
    CurrentPage = null;
}

public class BasePage : ContentPage
{
  // NO "InitializeContext". No XAML. Each subclass does that.
  public BasePage(){ }

  protected override void OnAppearing()
  {
    base.OnAppearing();
    App.PageAppearing(this);
  }
  protected override void OnDisappearing()
  {
    App.PageDisappearing(this);
    base.OnDisappearing();
  }

  public virtual void SaveData() {}
}
public partial class MyTextEditPage : BasePage
{
  public override void SaveData()
  {
    ... code to save text file being edited ...
  }
}

The first thing I do in Deactivated/OnPaused is set a flag: DidPause = true; (refers to declaration private static bool DidPause;). I check that flag in Activated/OnResume, to know that app is continuing after going into background (but was not killed).

Next, have some mechanism to save data that "may have changed" (aka "dirty flag" is set on them), but have not been saved to local files. Save them. (If there is changed information that has not yet been successfully sent to a server, that is more complex. I save locally first; what to do after that is beyond scope of this answer.)

Third, pause or shutdown anything that doesn't need to run while app is in background.


In OnResume, if (DidPause) { DidPause = false; ... } code to restore anything that got shutdown or paused.

In this case, whatever page was showing should still be showing. Data saving was just a precaution, in case the app never comes back.

else { ... } (DidPause not set): The app is starting for first time, or after being killed.

  • Related