The application lifecycle includes events such as startup, suspend, and resume. Every platform manages the application lifecycle differently, so implementing platform-specific code in iOS, Android, Tizen, Mac Catalyst and Windows projects would require some effort. However, .NET MAUI allows you to manage the app lifecycle in a unified way and takes care of performing the platform-specific work on your behalf. This article explains the app lifecycle and how you can manage your app’s behavior.
The App class
The App class is a singleton (single-instance) class that inherits from Application and that is defined inside the App.xaml.cs file. You can think of it as an object that represents your application running and includes the necessary infrastructure to handle resources, navigation, and the lifecycle. At a higher level, the App class exposes some fundamental members that you might need across the whole app lifecycle: the MainPage property you assign with the root page of your application, and methods you use to manage the application lifecycle that are described shortly.
Managing the app lifecycle
In .NET MAUI, the application lifecycle is handled by an object called Window
. When the application starts up, an instance of this class is created. This instance also allows you to subscribe for events that represent moments of the lifecycle, and that are summarized as follows,
Event |
Description |
Created |
Raised after the native window, or page for mobile apps. has been created. The cross-platform window will have a handler to the native one, but it might not be visible yet. |
Activated |
Raised when the window (or page for mobile apps) has been activated and focused. |
Deactivated |
Raised when the window, or page for mobile apps, has lost focus. |
Stopped |
Raised when the window, or page for mobile apps, is no longer visible. |
Resumed |
Raised when an app resumes after being stopped. This event can only be raised if the Stopped event was previously raised. |
Destroying |
Raised when the native window (or page) is being destroyed and deallocated. |
There are two ways for handling the app lifecycle events: overriding the CreateWindow
method in the App
class, and subclassing the Window
class.
Overriding the CreateWindow method
The runtime invokes a method called CreateWindow
to generate an instance of the Window
class when the application starts up. You can override this method to subscribe for the app lifecycle events. The following code shows an example,
public partial class App: Application {
public App() {
InitializeComponent();
MainPage = new AppShell();
}
protected override Window
CreateWindow(IActivationState activationState) {
Window window = base.CreateWindow(activationState);
window.Created += (sender, eventArgs) => {
// take actions here...
};
window.Activated += (sender, eventArgs) => {
// take actions here...
};
return window;
}
}
What you need to do is subscribe for one or more of the app events. As an example, the preceding code starts listening to the Created
and Activated
events. You will need to add your own logic to every event handler you subscribe, based on the type of event. For instance, if you were subscribing for the Destroying
event, in the event handler you could write code that stores the state of the app and of its data.
Subclassing the Window class
An alternative to handling events in the App
class directly is creating a class that derives from Window
, and that overrides the methods that represent events. Due to .NET naming conventions, event names are preceded by the On prefix so you will have OnCreated
, OnActivated
, OnStopped
etc. The following snippet shows an example about subclassing the Window
class,
public class CustomWindow: Window {
public CustomWindow(): base() {}
public CustomWindow(Page page): base(page) {}
protected override void OnCreated() {
base.OnCreated();
}
protected override void OnActivated() {
base.OnActivated();
}
}
Add your own logic inside each event handler. At this point, the App
class needs to create an instance of the Window
object via the new CustomWindow
class. This can be accomplished by overriding the CreateWindow
method as follows,
protected override Window CreateWindow(IActivationState activationState) {
CustomWindow window = (CustomWindow) base.CreateWindow(activationState);
return window;
}
Handling native events and custom handlers
The events described in this section are common to all the supported platforms and can be handled in a cross-platform approach. Behind the scenes, they map native events that you can fully handle in the MauiProgram
class. The following code shows how you can handle native events by invoking the ConfigureLifecycleEvents
method, which requires a using Microsoft.Maui.LifecycleEvents;
directive,
public static MauiApp CreateMauiApp() {
var builder = MauiApp.CreateBuilder();
builder.UseMauiApp < App > ().ConfigureFonts(fonts => {
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
}).
ConfigureLifecycleEvents(events => {
#if ANDROID
events.AddAndroid(android => android.OnBackPressed((activity) => {
return false;
}));
#endif
});
return builder.Build();
}
Preprocessor directives give you the option to configure events only for the desired platform. The list of native events is extremely long for Android, iOS and Windows, so you are encouraged to walk through the documentation if you plan to have deeper control over lifecycle events. You will also find explanations about defining and registering custom events, which still happens via the ConfigureLifecycleEvents
method.