maui-app-lifecycle

.NET MAUI App Lifecycle

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "maui-app-lifecycle" with this command: npx skills add davidortinau/maui-skills/davidortinau-maui-skills-maui-app-lifecycle

.NET MAUI App Lifecycle

App states

A MAUI app moves through four logical states:

State Meaning

Not Running App process does not exist.

Running App is in the foreground and receiving input.

Deactivated App is visible but lost focus (e.g. a dialog or split-screen).

Stopped App is fully backgrounded; UI is not visible.

Typical flow: Not Running → Running → Deactivated → Stopped → Running (resumed) or Not Running (terminated).

Cross-platform Window events

Microsoft.Maui.Controls.Window exposes six lifecycle events:

Event When it fires

Created

Window has been created (native window allocated).

Activated

Window has been activated and is receiving input.

Deactivated

Window lost focus but may still be visible.

Stopped

Window is no longer visible (backgrounded).

Resumed

Window returns to the foreground after being stopped.

Destroying

Window is being torn down (native window deallocated).

Important: Resumed never fires on the app's first launch. It only fires when returning from the Stopped state.

Subscribing to Window events

Option A – Override CreateWindow in App

public partial class App : Application { protected override Window CreateWindow(IActivationState? activationState) { var window = base.CreateWindow(activationState);

    window.Created += (s, e) => Log("Window Created");
    window.Activated += (s, e) => Log("Window Activated");
    window.Deactivated += (s, e) => Log("Window Deactivated");
    window.Stopped += (s, e) => Log("Window Stopped");
    window.Resumed += (s, e) => Log("Window Resumed");
    window.Destroying += (s, e) => Log("Window Destroying");

    return window;
}

}

Option B – Custom Window subclass with overrides

public class AppWindow : Window { public AppWindow() : base() { } public AppWindow(Page page) : base(page) { }

protected override void OnCreated() { /* init work */ }
protected override void OnActivated() { /* refresh UI */ }
protected override void OnDeactivated() { /* pause timers */ }
protected override void OnStopped() { /* save state */ }
protected override void OnResumed() { /* restore state */ }
protected override void OnDestroying() { /* cleanup */ }

}

Return it from CreateWindow :

protected override Window CreateWindow(IActivationState? activationState) { return new AppWindow(new AppShell()); }

Platform lifecycle event mapping

Android

Window event Android Activity callback

Created OnCreate

Activated OnResume

Deactivated OnPause

Stopped OnStop

Resumed OnRestart → OnStart → OnResume

Destroying OnDestroy

iOS / Mac Catalyst

Window event UIKit callback

Created WillFinishLaunching / SceneWillConnect

Activated DidBecomeActive

Deactivated WillResignActive

Stopped DidEnterBackground

Resumed WillEnterForeground

Destroying WillTerminate

Windows (WinUI)

Window event WinUI callback

Created OnLaunched

Activated Activated (foreground)

Deactivated Activated (background)

Stopped VisibilityChanged (false)

Resumed VisibilityChanged (true)

Destroying Closed

Platform-specific lifecycle events

Use ConfigureLifecycleEvents in MauiProgram.cs to hook directly into native callbacks:

builder.ConfigureLifecycleEvents(events => { #if ANDROID events.AddAndroid(android => android .OnCreate((activity, bundle) => Log("Android OnCreate")) .OnStart(activity => Log("Android OnStart")) .OnResume(activity => Log("Android OnResume")) .OnPause(activity => Log("Android OnPause")) .OnStop(activity => Log("Android OnStop")) .OnDestroy(activity => Log("Android OnDestroy"))); #elif IOS || MACCATALYST events.AddiOS(ios => ios .WillFinishLaunching((app, options) => { Log("iOS WillFinishLaunching"); return true; }) .SceneWillConnect((scene, session, options) => Log("iOS SceneWillConnect")) .DidBecomeActive(app => Log("iOS DidBecomeActive")) .WillResignActive(app => Log("iOS WillResignActive")) .DidEnterBackground(app => Log("iOS DidEnterBackground")) .WillTerminate(app => Log("iOS WillTerminate"))); #elif WINDOWS events.AddWindows(windows => windows .OnLaunched((app, args) => Log("Windows OnLaunched")) .OnActivated((window, args) => Log("Windows Activated")) .OnClosed((window, args) => Log("Windows Closed"))); #endif });

State preservation pattern

Save and restore transient state during backgrounding:

protected override void OnStopped() { base.OnStopped(); Preferences.Set("draft_text", _viewModel.DraftText); Preferences.Set("scroll_position", _viewModel.ScrollY); }

protected override void OnResumed() { base.OnResumed(); _viewModel.DraftText = Preferences.Get("draft_text", string.Empty); _viewModel.ScrollY = Preferences.Get("scroll_position", 0.0); }

For larger state, use SecureStorage or file-based serialization instead of Preferences .

Key behavioural notes

  • Resumed ≠ first launch. Resumed only fires when returning from Stopped . On first launch the sequence is Created → Activated .

  • Deactivated ≠ Stopped. A dialog or split-screen triggers Deactivated without Stopped .

  • Android back button may call Destroying without Stopped if the activity finishes.

  • iOS scene lifecycle is used on iOS 13+; older delegate methods are still forwarded.

  • Multiple windows (iPad, Mac Catalyst, desktop Windows): each Window instance fires its own events independently.

  • Keep lifecycle handlers fast. Long-running work should use Task.Run or background services to avoid ANR/watchdog kills.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

maui-performance

No summary provided by upstream source.

Repository SourceNeeds Review
General

maui-data-binding

No summary provided by upstream source.

Repository SourceNeeds Review
General

maui-rest-api

No summary provided by upstream source.

Repository SourceNeeds Review
General

maui-dependency-injection

No summary provided by upstream source.

Repository SourceNeeds Review