Avalonia如何处理应用的生命周期事件 Avalonia Application lifetime

Avalonia 应用生命周期由 AppBuilder 与 Lifetime 接口协同驱动,分三阶段:Program.Main() 入口配置启动;App.Initialize() 加载资源;OnFrameworkInitializationCompleted() 创建主窗口;Lifetime 接口响应系统状态,Window 事件处理 UI 层级生命周期。

Avalonia 应用的生命周期事件处理不是靠传统 WinForms 或 WPF 那样的 Application.Run(),而是由 AppBuilder 和具体的 Lifetime 接口 协同驱动,核心控制点集中在 Program.Main()App.Initialize()OnFrameworkInitializationCompleted() 三个阶段。

入口与启动:Program.Main() 是起点,但不直接操作 UI

这是 .NET 运行时真正进入应用的第一行代码,此时 Avalonia 尚未初始化,不能创建窗口或访问 UI 类型:

  • BuildAvaloniaApp() 负责配置 AppBuilder(绑定 App 类、检测平台、启用日志/ReactiveUI 等)
  • StartWithClassicDesktopLifetime(args) 启动桌面应用模式,接管消息循环和退出逻辑
  • macOS/iOS 等平台可追加参数如 ShutdownMode.OnLastWindowClose 控制退出时机

框架就绪:App.Initialize() 加载资源,OnFrameworkInitializationCompleted() 创建主窗口

这两个方法是真正“可用”的分水岭:

  • Initialize():仅做轻量初始化,如调用 AvaloniaXamlLoader.Load(this) 加载 App.axaml 中的样式、主题、字体等全局资源;不创建任何窗口,也不依赖 UI 线程
  • OnFrameworkInitializationCompleted():框架已完全就绪,UI 系统可安全使用。此时根据 ApplicationLifetime 类型创建主窗口:
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
    desktop.MainWindow = new MainWindow();

运行中事件:通过 Lifetime 接口监听系统级状态变化

Avalonia 提供多个 Lifetime 接口,用于响应跨平台的应用状态变更:

  • IActivatableLifetime:监听激活/失活(如 macOS 切换到其他 App 后再切回)
  • IClassicDesktopStyleApplicationLifetime:提供 ShutdownRequested(用户点击关闭按钮前)、Exited(进程即将退出)等事件
  • iOS/macOS 注意:接口绑定需在正确时机完成,比如 iOS 中 IActivatableLifetime 必须基于非空 appDelegate 实例注册,否则失效

窗口级生命周期:Window 自身也有独立事件链

每个 Window 实例还有一套更细粒度的生命周期事件,适合做 UI 层面的清理或交互控制:

  • Initialized:控件属性已设置,但尚未布局
  • Loaded:已加入视觉树,布局完成,可安全访问 RenderSize 或触发动画
  • Closing:窗口即将关闭,可通过 e.Cancel = true 拦截(例如弹出保存提示)
  • Closed:窗口已销毁,适合释放非托管资源

基本上就这些。关键在于分清层级:应用级事件靠 Lifetime 接口,窗口级事件靠 Window 实例,而初始化顺序必须严格遵循框架准备就绪的节奏,不能越界操作。