频道栏目
读书频道 > 系统 > windows > Windows运行时编程权威指南
3.4.2 Windows应用商店应用的终止
2015-04-01 13:19:39     我来说两句
收藏   我要投稿

本文所属图书 > Windows运行时编程权威指南

《Windows 运行时编程权威指南》分为两部分,共11章:第一部分(第1~3章)囊括了所有WinRT和Windows应用商店应用开发人员必须了解的重要概念,包括WinRT 类型系统及其设计原则、异步调用、程序包文件,以及应  立即去当当网订购

本章已用大量篇幅介绍了应用如何高效地进行内存管理。这一点至关重要,因为许多移动PC的内存容量无法与传统的桌面PC相比。但即使所有的Windows应用商店应用都按照本章介绍的方法进行内存管理,仍然有可能出现用户启动了大量Windows应用商店应用,以致系统内存耗尽的情况。这时,用户便必须将某些当前正在运行的应用关闭,以便能够运行一些新的应用。但哪些应用应被关闭?一种比较好的选择是关闭那些占用内存最多的应用。但用户如何知晓这一点?对于此问题,并无完美的解决方案。即便有这样的方案,也将花费用户很大精力来找出这类应用,并对其进行管理。

因此,对于Windows应用商店应用,微软让操作系统代替用户来应对该问题,尽管作为软件开发人员的你也必须致力于解决该问题。当内存将被耗尽时,Windows会自动终止那些用户当前未与之交互的应用。当然,用户无需知晓其发生,因为用户此时并未与这些应用进行交互。系统记录了哪些应用正在运行,并允许用户通过Windows应用商店应用任务列表(Windows键+Tab键)切换至该应用。当用户切换回该应用时,操作系统将重新启动该应用。这样,用户便可再次与之进行交互。

应用占用的内存越少,被操作系统终止的几率便越小。

当然,应用可利用它所占用的内存来维护用户的状态。当操作系统将应用终止时,内存将被释放,它所维护的状态也将被丢弃。这正是开发人员需要介入的地方。在被终止前,应用必须将其状态保存到磁盘中;而当应用被重新启动时,将恢复原先的状态。如果你的应用正确地做到了这一点,将使用户产生一种该应用从未被终止,一直驻留在内存中的错觉(虽然在应用重新初始化时,应用的启动画面将被显示)。其结果是用户完全不必对应用的生命期进行管理,这一点对于内存容量有限的移动PC尤为有用。

前面我们介绍了Resuming事件以及当操作系统恢复应用的线程时,如何引发该事件。WinRT的基础类Application提供了一个Suspending事件(实际上是对CoreApplication类的Suspending事件的包装)。在某个应用的线程被挂起之前,该事件将被引发,以使应用可将其状态持久化到用户的某个磁盘文件中。Windows要求应用必须在5秒之内完成挂起;如果超时,Windows将终止该应用。虽然Windows设定的时间上限是5秒,但要获得Windows应用商店的证书,应用必须在2秒内完成挂起。如果遵循了第3.3节“XAML页面导航”中所介绍的模型,你只需在自己的挂起代码中创建一个磁盘文件,并将字典列表序列化至该文件中便可。此外,还需调用Frame对象的GetNavigationState方法,以返回一个表示了用户在应用中导航时所构建的所有页面集合的String对象;然后将该字符串也序列化到那个磁盘文件中。

虽然应用被挂起,操作系统仍可能将其终止,以便为其他应用腾出内存空间。如果操作系统选择了将你的应用终止,将不会给出任何额外通知;操作系统所做的仅是简单地将应用的进程结束。理由显而易见:如果系统允许你的应用在终止之前执行代码,该应用便有可能申请更多的内存,而这只会雪上加霜。避免出现这种情况的关键在于:应用必须在接收到Suspending事件之前保存其状态,因为一旦操作系统决定终止该应用,它将不会有任何机会去执行更多的代码。

即使操作系统终止了你的应用,也会给用户造成该应用仍在运行的错觉,同时允许用户切换回刚才被终止的应用。图3.9展示了系统的任务列表以及App1应用被终止后的任务管理器。请注意,任务列表中显示了App1应用,以便用户能够切换回它。然而,任务管理器不会显示该App1应用的任何项,因为它已不在内存中驻留。



当用户切换回某个被终止的应用时,操作系统将执行该应用的主视图激活(并显示其启动画面)。该应用此刻必须对其自身初始化,并恢复到被终止时的状态。该应用被终止这个事实对用户必须透明。这一点十分重要。就用户而言,你的应用永远不应停止运行:无论它是处在运行中、被挂起、甚至被终止,它应随时听候用户的调遣。

当应用被激活后,其Main方法将运行,接着主视图线程将被创建,App的构造方法将执行,然后Application类的虚方法OnWindowCreated将被调用,之后将执行某个虚方法OnXxx(具体执行哪个虚方法,依赖于应用被重新激活的原因)。如果应用因宿主视图激活而激活,则无需恢复该应用被挂起之前的状态。但如果应用因主视图激活而启动,你便需要了解该应用被重新激活是否是由于之前操作系统将其终止。

所有的虚方法OnXxx都作为实现了IActivatedEventArgs接口的类型的参数而被传递。
IActivatedEventArgs接口拥有一个可返回ApplicationExecutationState类型的值的PreviousExecutionState属性。ApplicationExecutationState是一个枚举类型,且当PreviousExecutionState属性的返回值为ApplicationExecutionState.Terminated时,你的应用便知道自己被重新启动是因操作系统之前将其终止。此时,你的代码应打开之前用于序列化应用状态的用户磁盘文件,对字典列表反序列化,抓取含有框架页面编码的字符串,并将其传入Frame对象的SetNavigationState方法。当调用SetNavigationState方法时,它会将Frame对象重置回应用被挂起时的状态,以便当该应用被挂起时,用户所看到的内容与之前完全一致。对用户而言,你的应用看上去从未被终止。

注意,来自内存的压力并非应用被终止的唯一原因。其他原因包括:用户按下Alt+F4关闭某个应用;将应用窗口从屏幕顶部拖动到底部,并保持几秒;或在任务列表中右击该应用,并选择关闭(Close)。此外,当用户注销或关机时,操作系统会将全部应用关闭。在所有这些场景中,操作系统的确会引发窗口的VisibilityChanged事件,随后将引发应用的Suspending事件,使应用有机会将其状态保存下来。然而,在以后启动该应用时,不应恢复其状态,因为用户已经明确地将其关闭,而非操作系统隐式地将其终止。如果检查PreviousExecutionState属性,你将发现在所有这些场景中,它都将返回ApplicationExecutionState.ClosedByUser。

用户可通过任务管理器强制结束某个应用。当然,应用也可通过抛出一个未经处理的异常而自我终止。此外,如果某个应用虽然正在运行,但用户希望将其卸载,或系统准备将该应用升级到更新的版本时,Windows也会自动将该应用终止。在所有这些场景中,当日后该应用重新启动时,它应对自身进行初始化,而无需恢复到任何先前的状态,因为那些状态可能已被破坏,而这可能会在一开始便造成一个未经处理的异常。如果你检查PreviousExecutionState属性的值,你将发现在这些场景中,它都将返回ApplicaitonExecutionState.NotRunning。

Windows应用商店应用无需将自身关闭,并且也没有提供任何用户界面元素使用户可将其关闭。如果你的应用违背了该规则,将无法通过Windows应用商店的认证。CoreApplication类提供了Exit方法及Exiting事件。这些成员仅为应用开发时的调试而设计,例如内存泄露检测、单元测试等。当你将自己的应用提交到Windows应用商店进行认证时,Windows.UI.Xaml.Application不会对这些成员进行包装。对于你的App类,使用这些成员并非易事。


您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:3.4.1 Windows应用商店应用的挂起
下一篇:3.4.3 如何设计应用类代码的结构
相关文章
图文推荐
排行
热门
最新书评
文章
下载
读书
特别推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站