1. Lifecycle
Windows8应用的生命周期,与Windows Phone及其他手机平台相比更加简单,Windows8应用只有:未运行、运行、挂起,三个状态。其状态如下图:
当应用切换到后台,或者系统电量低时,应用会被挂起,挂起后的应用还驻留在内存中,页面的导航状态,以及当前页面的内容等一切内容都在。当用户切换回应用时,系统自动恢复到挂起前的状态,我们不需要做任何工作,唯一需要的可能是要刷新一下数据,比如基于Location的应用和新闻类的应用,因为在挂起的这段时间里,数据可能已经发生了变化。
系统会终止挂起的应用,以节省内存和电力。这时应用就从内存里消失了。如果用户再次切换回应用里,就要重新启动了。Windows8应用不应该主动退出,也就是不应该提供退出操作。不过,用户可以主动地关掉一个应用,如使用关闭手势,Alt+F4终止应用。在使用关闭手势和Alt+F4后,应用会被挂起10秒钟,然后被终止。
好的应用,应该是,在不是被用户主动关闭(Alt+F4,关闭手势)的情况下,当应用再次被启动时,应恢复到挂起前的状态,以给用户应用始终都在运行的感觉。这就需要我们在应用被挂起时,应该保存应用的状态数据。以便在重新启动时恢复界面。
2. 应用数据的保存和恢复
应用的数据可会为应用数据(app data)和会话数据(session data),应用数据对用户来说是持久的,在多个会话中保持一致的,比如用户的设置信息等。而会话数据是临时的,只在本次会话中有效的数据。Windows8的建议是,应用数据应在发生改变时立即保存,而会话数据则在应用挂起时保存,在应用重新启动时恢复。
Windows提供了 Windows.Storage.ApplicationData,这个对象分别提供了LocalFolder、LocalSettings和RoamingFolder、RoamingSettings,2组4个属性对象,来分别进行本地和漫游的应用数据保存,如果把数据保存到漫游的对象里,则Windows会自动在用户的不同设备间同步数据。
3. 会话数据的保存和恢复
会话数据通过SuspensionManager和LayoutAwarePage,来进行保存和恢复。在添加了BasicPage模版页到工程后,VS2012会自动添加这两个类到工程的Common目录里。
3.1 SuspensionManager
SuspensionManager负责对会话数据的管理,使用它可以在应用启动时恢复Frame的导航状态和页面的状态,在应用挂起时保存这些数据.
sealed partial class App : Application { public App() { this.InitializeComponent(); // 在应用挂起时,获得响应 this.Suspending += OnSuspending; } protected async override void OnLaunched(LaunchActivatedEventArgs args) { Frame rootFrame = Window.Current.Content as Frame; // Do not repeat app initialization when the Window already has content, // just ensure that the window is active if (rootFrame == null) { // Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); // 注册我们要保存和恢复的Frame HelloWorld.Common.SuspensionManager.RegisterFrame(rootFrame, "appFrame"); if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { //当状态是Terminated时,恢复应用的会话数据 await HelloWorld.Common.SuspensionManager.RestoreAsync(); } // Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null) { if (!rootFrame.Navigate(typeof(MainPage), args.Arguments)) { throw new Exception("Failed to create initial page"); } } // Ensure the current window is active Window.Current.Activate(); } private async void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); // 应用要被挂起了,保存应用的状态,并退出后台的操作,打开的文件等 await HelloWorld.Common.SuspensionManager.SaveAsync(); deferral.Complete(); }
在启动时,并不是所有的情况都应该恢复数据,代码中判断了只有在args.PreviousExecutionState是Terminated状态时才会调用RestoreAsync。PreviousExecutionState是这次启动之前程序的状态,是一个ApplicationExecutionState类型的枚举值,一共有5种状态。只有Terminated是应用由系统在挂起并终止的状态,需要恢复会话数据,其它情况下的终止,像重启、重新安装、用户主动关闭等,我们通常认为是会话已经结束,重新启动新的会话即可,不需要恢复。
NotRunning |
The user first activates the app after:
The user closes the app through the close gesture or Alt+F4 and activates it within about 10 seconds of closing it. |
Display its initial UI and perform initialization tasks. |
Running |
The app is activated through a secondary tile or one of the activation contracts and extensions while it is running. |
Respond to the activation event as appropriate. |
Suspended |
The app is activated through a secondary tile or one of the activation contracts and extensions while Windows is suspending it or after Windows has suspended it. |
Respond to the activation event as appropriate. |
Terminated |
Windows successfully suspends the app and then it is terminated. For example, Windows can terminate a suspended app if the system is running low on resources. Some apps, such as games, can be pretty resource intensive. |
Restore itself to the way the user left it, rather than starting fresh. Use data saved during app suspension. Refresh content or network connections that may have become stale. |
ClosedByUser |
The user closes the app through the close gesture or Alt+F4 and takes longer than 10 seconds to activate the app again. |
Display its initial UI and perform initialization tasks, rather than restoring its previous state. |
3.2 LayoutAwarePage
LayoutAwarePage是Page的一个派生类,它提供了两个方法SaveState和LoadState,分别用于保存和恢复会话数据
protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState) { // 从pageState中,读取保存的数据,恢复到界面上 } protected override void SaveState(Dictionary<String, Object> pageState) { // 将需要保存的数据,保存到pageState }
更详细内容可以参考这里:http://msdn.microsoft.com/en-us/library/windows/apps/hh986968.aspx