Windows 10 universal Windows platform (UWP) app lifecycle
传统的Win32程序只有运行和不运行两种状态,UWP应用增加了一种挂起(suspend)状态。挂起意味着应用失去了执行资源,但是其状态还保存再内存中,可以随时被恢复,或者被清除。
挂起状态下的应用有几种方式可以获取运行资源:
- 幕后任务 (background task)
- 延续运行 (extended execution)
- 活动支援性运行(activity sponsored execution),比如后台媒体播放
有一些任务在挂起或者应用终结的时候依然可以运行,比如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
如果在后台或者锁屏的时候延续应用的运行。
其他参考
- Run in the background indefinitely
- The Lifecycle of a UWP App
- How to trigger suspend, resume, and background events in Windows Store apps
- Run Background Task Indefinitely in UWP
- Windows 10 UWP - stop background task if foreground app is running
(完)