Windows 10 universal Windows platform (UWP) app lifecycle

传统的Win32程序只有运行和不运行两种状态,UWP应用增加了一种挂起(suspend)状态。挂起意味着应用失去了执行资源,但是其状态还保存再内存中,可以随时被恢复,或者被清除。

挂起状态下的应用有几种方式可以获取运行资源:

有一些任务在挂起或者应用终结的时候依然可以运行,比如How to download a file.

Windows 10 1607引入了两种应用状态:Running in foreground和Running in background。在应用被加载或者激活的时候,它们首先进入后台。从后台到前台,会接收到LeavingBackground 事件。

当应用被加载的时候,会触发OnLaunched事件,其参数LaunchActivatedEventArgs带有部属PreviousExecutionState(类型为ApplicationExecutionState),可以用来判断之前的执行状态:

  • NotRunning,应用未运行
  • Suspended,应用被挂起,可能最小化了,或者一段时间没有交互
  • Terminated,应用挂起后被终止
  • ClosedByUser,用户关闭应用
  • Running,应用已经有实例在运行

值得注意的是,应用可以选择加入预加载(Handle app prelaunch)。操作系统可以帮助应用显示启动界面Adding a splash screen

应用除了可以被用户加载(launch)以外,还可以被系统激活(activate)。激活的场景可以在ActivationKind中查看。

虽然OnActivated可以应付所有激活场景,但是还是推荐使用特定的回调来处理具体的激活:

  • OnCachedFileUpdaterActivated
  • OnFileActivated
  • OnFileOpenPickerActivated OnFileSavePickerActivated
  • OnSearchActivated
  • OnShareTargetActivated

从1607开始Windows 10可以在同一个应用进程内执行后台任务,参考 Background activity with the Single Process Model。为此新增了两个事件EnteredBackground 和LeavingBackground。

切换到前台时,会触发LeavingBackground 事件。此事件后,用户就可以看见UI了。切换到后台时,会触发EnteredBackground。在桌面环境下,这意味着应用被最小化了。应用可以停掉一些无关紧要的任务以节省资源:Reduce memory usage when your app moves to the background state 。EnteredBackground也是保存应用状态的好时机,参考Store and retrieve settings and other app data。当你的应用有后台任务的时候,它可能会直接跳到前台运行,而不经过挂起状态。

当应用被最小化之后,如果在一段时间内没有被复原,以及期间没有幕后任务在运行(比如延续运行、幕后任务、活动支援性运行等等)应用就会被挂起。在锁屏的时候,如果没有延续运行,那么应用也会被挂起)。在Application.Suspending 事件中,应用要释放多余的资源,否则会因占用资源过多被系统终结。在这个事件中,应用不能执行太多代码,关于资源限制,可以查看SuspendingOperation 。可以用SuspendingOperation的GetDeferral 来延缓进入挂起状态,以等待异步操作完成。

从挂起中恢复,应用会接收到Application.Resuming 事件。如果是被系统激活,那么在Rsuming之后会收到Activated 事件。如果应用已经被杀死了,那么不会有Resuming事件,而是会有OnLaunched事件。Resuming事件不会发生在UI线程,如果需要更新UI线程,参考Update the UI thread from a background thread以及Guidelines for app suspend and resume.

应用有可能Crash。重新加载之后其前续状态为NotRunning。

Handle app prelaunch

介绍系统如何预加载应用。

Handle app activation

应用被激活时,系统发送CoreApplicationView.Activated事件。激活的类型可以在ActivationKind中查看。

Windows.UI.Xaml.Application预定义了几种激活类型,如果需要通用的,重载OnActivated。

为什么一直在讨论OnLaunched

Handle app suspend

当用户重新打开一个挂起并终止的APP,系统会先发送Activated事件(无法被Windows.UI.Xaml.Application捕捉到),然后触发OnLaunched回调。

Handle app resume

在挂起时,系统会保存应用状态,所以在复原的时候,应用看到的还是挂起之前的数据状态。Resuming事件的处理器格式是: EventHandler<Platform::Object>,实际上就是:

void MainPage::App_Resuming(
    Windows::Foundation::IInspectable const& /* sender */,
    Windows::Foundation::IInspectable const& /* e */)
{
    // TODO: Refresh network data, perform UI updates, and reacquire resources like cameras, I/O devices, etc.
}

在Visual Studio调试的时候,应用是不会挂起的,需要在VS中主动发送Suspend事件。

Free memory when your app moves to the background

解释如何释放不需要的内存。

Postpone app suspension with extended execution

如果在后台或者锁屏的时候延续应用的运行。

其他参考

(完)