掌握了Windows 8有关的生命周期模型,能够帮助用户轻松管理应用程序的运行,也可以使开发人员制作出具有极高用户体验的应用程序,即便应用在后台进行,也不会影响到设备的性能和电池情况。正确使用生命周期事件,。即便应用不再屏幕上运行显示,也可以让用户感觉到应用处在活跃状态。
一般情况下,在使用诸如笔记本,平板,或手机时,如果我们暂不需要使用某个程序,同时希望让其自身仍保持运行状态,从而使得应用间可以迅速方便的切换,但这会使设备上电量经常不足。由于考虑到这个方面,在Windows 8 Metro风格应用的生命周期模型设计中,具有了使应用保持响应,增加电池寿命,提供良好的持续的性能感受的方面。Metro风格的应用带来的几乎都是全屏的,沉浸其中的体验模式。比如在Windows 8中新的生命周期模型,关注于前台的应用,确保用户正在使用的应用程序保持良好的用户体验,并且为此调动设备的各个方面达到用户体验要求。
下面来看看生命周期模型中的状态,并告诉你怎样合理使用生命周期。
15.1 Metro 应用生命周期介绍
Metro风格的应用在任何时间,都是四种状态中的一种,四种状态分别指非运行状态,运行状态,挂起状态,终止状态。当应用程序在状态间转换时,它会收到生命周期的事件,对事件正确处理,可以带给用户一个持续并高性能体验。
15.1.1 状态交互图
Metro风格的应用状态转换如下图15_1所示。
图15_1 状态转换图
用户在启动应用程序,切换应用程序和关闭应用程序的操作过程中,所有Metro风格的应用在以上状态中转换。所以一个应用程序,需要对以下几个生命周期事件进行处理,他们会在状态转换的过程触发。
激活事件:在从非运行状态到运行状态转变时触发。
挂起或检查点(对WinJS而言)事件:在从运行状态到挂起状态转变时触发。
恢复事件:在从挂起状态到运行状态转变时触发。
15.1.2 挂起状态
一般来说,当用户切换到其他应用时,Metro风格的应用会停止运行,Windows会将不在前台的应用挂起。当应用处在挂起状态,它就被冻结在内存中,虽然此刻应用不能运行,但当用户返回到这一应用时,Windows可以迅速地恢复其运行。通过这种方法,Windows赋予了前台应用更多的系统资源,并确保后台应用程序不会耗尽电池电量。
当应用离开前台时,Windows会延时等待几秒,期间用户可以迅速切换回此应用,等待结束则尝试挂起应用。当Windows试图挂起应用时,应用会接收到事件,而这个事件是应用中之前被注册的Suspending或Checkpoint (JavaScript)事件,应用在这个时候,可以存储必须保存在存储器中的数据。通常应用返回会恢复原来的样子,并不需要持久的,保存在存储器中的数据,因为所需数据仍在内存中,但为避免Windows终止应用时释放了系统资源的情况,需要将这些数据存在存储器中。要保存足够的数据资源,使用户从应用挂起状态,可以返回到之前所在的应用的特定位置或状态。按照这个方法,用户会感觉到应用始终保持活跃。
如果应用在接到挂起事件5秒钟内,没有从其挂起事件处理函数返回,Windows将会终止这个应用。所以注意不要在挂起事件处理函数中做过多操作,保存完应用程序的数据后即刻返回。
下面的例子是一个证券类应用,应用可以通过挂起事件,保存用户浏览的最后一支股票,和一个股价图的时间跨度。如果应用被终止了,应用重启后可返回到用户上次所看视图上来。此外建议股票类应用程序中,利用挂起事件发送一个本地的Tile通知,使应用在被Windows挂起前更新信息到最新状态。
下面代码是在应用对象上使用挂起事件,处理应用的挂起。
public App(){
InitializeComponent();
this.Suspending += new SuspendingEventHandler(OnSuspending);
}
async protected void OnSuspending(object sender, SuspendingEventArgs args)
{
// 挂起事件处理函数可以对应用状态进行存储,在存储用户当前浏览信息时,由于文件写入是异步进行的,所以我们设置了一些延迟,确保直到文件写入完成后再挂起
SuspendingDeferral deferral = args.SuspendingOperation.GetDeferral();
// 这里创建了一个SuspensionManager类,处理将Session中数据添加到一个字典,之后将数据序列化存入文件
SuspensionManager.SessionState["lastSeenStock"] = stock; SuspensionManager.SessionState["lastSeenRange"] = range;
await SuspensionManager.SaveAsync();
// 发送客户端通知
Tile.SendTileUpdate(stock, stockInfo.Change, stockInfo.LastSale, stockInfo.LastSaleTime, stockInfo.Open);
deferral.Complete();
}