如何阻止MAUI应用被关闭?Windows及Android平台适配问询
问题描述
我知道当前问题比较宽泛,但有没有办法阻止Windows和Android平台上的MAUI应用被关闭?我注意到MAUI的Window类没法像WPF那样重写OnClosing方法并设置Cancel为true,这应该是MAUI跨平台特性导致的。
另外,能不能把应用转为服务或者用其他方式让它在后台运行,等计算完成后推送通知?
目前我只尝试过重写Window类的OnDestroying方法,但不知道后续该怎么做。
相关代码
App.xaml.cs
public partial class App : Application { public App() { InitializeComponent(); MainPage = new AppShell(); } protected override MyWindow CreateWindow(IActivationState activationState) { return new MyWindow(MainPage); } }
MyWindow.cs
public class MyWindow : Window { public MyWindow() : base() { } public MyWindow(Page page) : base(page) { } protected override void OnDestroying() { System.Diagnostics.Debug.WriteLine("Destroying"); } protected override void OnStopped() { System.Diagnostics.Debug.WriteLine("Stopping"); } protected override void OnDeactivated() { System.Diagnostics.Debug.WriteLine("Deactivating"); }
生命周期日志异常
我还发现OnStopped的触发早于OnDestroying,这和MAUI官方文档描述的不符,让我很困惑。
输出日志:
Destroying Stopping Deactivating The program '[9736] MauiApp.exe' has exited with code 0 (0x0).
解决方案与说明
一、阻止应用关闭的实现方式
MAUI没有跨平台的OnClosing拦截机制,需针对Windows和Android分别做平台特定处理:
Windows平台
通过挂钩Win32的WM_CLOSE消息拦截窗口关闭:
- 获取窗口句柄;
- 重写窗口过程(WndProc)拦截
WM_CLOSE; - 根据业务逻辑决定是否取消关闭,比如弹出确认对话框,用户选择取消则终止关闭流程。
示例代码(Windows平台项目中实现):
// Platforms/Windows/App.xaml.cs protected override void OnLaunched(LaunchActivatedEventArgs args) { base.OnLaunched(args); var window = Application.Current.Windows[0].Handler.PlatformView as Microsoft.UI.Xaml.Window; IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window); SetWindowLongPtr(hwnd, GWLP_WNDPROC, new IntPtr(WndProcDelegate)); } private delegate IntPtr WndProcDelegate(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam); private static WndProcDelegate WndProcDelegate = WndProc; private static IntPtr WndProc(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam) { if (msg == WM_CLOSE) { var dialog = new Microsoft.UI.Xaml.Controls.ContentDialog { Title = "确认关闭?", Content = "当前有任务正在运行,确定要关闭吗?", PrimaryButtonText = "确定", SecondaryButtonText = "取消" }; var result = dialog.ShowAsync().GetAwaiter().GetResult(); if (result == Microsoft.UI.Xaml.Controls.ContentDialogResult.Secondary) { // 取消关闭操作 return IntPtr.Zero; } } return User32.CallWindowProc(IntPtr.Zero, hwnd, msg, wParam, lParam); } // Win32 API声明 [DllImport("user32.dll")] private static extern IntPtr SetWindowLongPtr(IntPtr hwnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll")] private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam); private const int GWLP_WNDPROC = -4; private const uint WM_CLOSE = 0x0010;
Android平台
Android无法完全阻止用户强制关闭,但可做部分拦截:
- 重写Activity的
OnBackPressed方法,拦截返回键触发的关闭; - 监听
ACTION_CLOSE_SYSTEM_DIALOGS广播,处理最近任务列表的关闭操作(无法阻止系统强制终止); - 若需后台持续运行,申请
FOREGROUND_SERVICE权限,将应用转为前台服务。
二、后台运行与通知推送
MAUI需通过平台特定服务实现后台运行,完成计算后推送通知:
Windows平台
创建Windows后台任务(Background Task),将计算逻辑移至后台任务执行,完成后通过ToastNotificationManager发送通知。
Android平台
创建前台服务(Foreground Service),在服务中执行计算任务(前台服务需显示持续通知避免被系统杀死),完成后通过NotificationManager推送通知。
跨平台层面可通过MAUI的DependencyService统一调用各平台实现,保持业务逻辑一致。
三、生命周期触发顺序异常说明
你遇到的OnDestroying先于OnStopped触发的问题,可能是调试环境的特殊情况或平台差异导致。建议在Release模式下测试,并分别验证Windows和Android平台的生命周期事件顺序——MAUI的生命周期事件在不同平台上的映射存在细微差异。
内容的提问来源于stack exchange,提问作者Artur Wyszomirski

