当前位置: 首页 > news >正文

Windows Phone7 不温不火学习之《应用程序生命周期》

在Windows Phone 上运行的应用程序从开始到程序运行结束,其整个生命周期都是由Windows Phone 的执行模型所支配。执行模型被设计的目的就是为终端用户实时提供快速的、反应灵敏的体验。故,Windows Phone 7在设计的初衷是以单任务设计为主导,虽说在不久的将来微软会步苹果之后为自己的手机平台添加多任务,但那是后话。

  Windows Phone 执行模型还维护着用户使用应用程序和查看页面所产生的日志。利用该日志就能定义电话后退键所遵循的后退路径,从而提供给用户一个能够回退到不同应用程序和浏览页面的后退选项。

  当用户通过导航键功能离开某一应用程序时,操作系统执行挂起该程序的步骤被称之为tombstoning,中文名称叫:“墓碑机制”。操作系统会维护应用程序状态信息。如果用户返回到被挂起的应用程序程序中,此时操作系统会继续执行被挂起应用程序的进程,并传递状态数据给此应用程序。

  一个应用程序会在用户切换离开它时被逻辑删除,然而除了这个一般规则仍然存有一些例外。操作系统可能需要额外的资源保证前台运行程序的正常活动,那么此时在操作系统运行的运应用程序有可能在任何时候被逻辑删除,这点跟Android 有点相似,唯一不同的是,Andriod 的KILL是杀死ACTIVITY页面,而不是杀死应用程序,我记得没错的话,应该是这样。

  注意:在一般情况下调用应用程序并不会被逻辑删除,但是当操作系统开启一个应用时发现需要比当前可用资源更多的资源时,那么应用程序就可能被逻辑删除。

  

  由于Windows Phone 7是单任务手机操作系统,故与多任务为原型的Android 相比应用程序生命周期要简单得多,Windows Phone 7的生命周期示意图为如下:

根据上图与Windows Phone 7生命周期相关的事件共分为以下五个部分:

  • 启动
  • 运行
  • 关闭
  • 禁止
  • 激活

而Android 的Activity 生命周期要来得复杂一些,具体看下图:

根据上图,Android 生命周期事件相关的共分为7大部分:

  • 创建
  • 重新启动
  • 活动可视时开始
  • 活动与用户交互之前
  • 被挂起时
  • 被停止时(有可能被销毁)
  • 被销毁时

由于本篇是讲述Windows Phone 7这里只和Android 的生命周期一个小小的比较,就不深入讲Android 内容,读者有兴趣的可以找一下相关的资料,下面继续Windows Phone 7 的生命周期。

1.启动

  当用户点击了手机上应用程序安装列表的某一应用程序,或者点击了开始屏幕上的代表某一应用程序的小方块图标 ,此时应用程序就被启动了。无论用户以哪种方式启动应用程序,该程序的实例就会被创建。当应用程序被启动了,也就是一个启动事件被触发了。处理这个启动事件时,应用程序应该从一个独立的存储中读取所有必要的数据来为用户创建一个新的应用程序会话进程。应用程序不应该试图从以前的应用程序实例中恢复瞬时状态。此是这是一个全新的应用实例。

  Note that:启动和激活事件是互斥的。

2.运行

  当启动事件被触发了,一个应用程序就开始运行了。应用程序处于运行状态时,用户进行浏览该应用程序的页面等相关操作,此时应用程序会自己管理自己的状态。如果应用程序处于运行状态,那么与执行模型相关的唯一操作就是逐步的保存设置以及其他应用程序持久化数据,这样做的目的是为了避免当应用程序的状态发生改变时需要保存大量的数据。

3.关闭

  应用程序处于运行状态之后的状态是取决于用户采用了哪种操作。一个可能的操作是用户按下手机的回退键从而回退到应用程序的前一页面,甚至翻过了应用程序的第一个页面。当这种情况发生时,关闭事件会被触发,从时应用程序被终止 了。处理关闭事件,应用程序应该把所有的持久化数据保存到独立的存储中。此时没有必要保存瞬时状态数据,即那些只有和前应用程序实例相关的数据。因为用户如果要返回一个己经被终止的应用程序,唯一的方法应当是启动它,打开它的首页。这就是单任务的好处。

4.禁止

  如果一个应用程序正在运行,随后在操作系统前台被另一个应用程序或者体验替代,例如,锁屏或者启动一个Chooser,这时第一个应用程序将会被禁止。禁止相当于Android 的onPause事件。此时如果操作检测到资源不足,可能会对该程序进行逻辑删除。由于会存在被逻辑删除的危险,所以并不能保证一个被禁止的应用程序会被重新激活,所以在此事件的处理中应用程序需要一直把持久化数据保存到一个独立的存储空间。

  Note that:禁止事件处理程序所进行的所有操作必须在10秒钟内完成,否则操作系统将会直接终止应用程序而不是逻辑删除。

5.激活

  当一个应用程序被禁止后,有可能这个应用程序永远不会被再次激活。用户可能会从头再重新启动该应用程序,从而得到一个新的应用程序实例。或者用户可以启动其他几个应用程序,这样就会把处于应用程序堆栈最后的即使利用回退键也不可能到达的欺骗性程序关闭掉。当然用户也有继续要使用原应用程序的可能性。这种情况可能会发生在用户不停地敲击回退键来达到指定应用程序目的。这个和Android的回退键倒是十分相似。

  开发人员可以使用墓碑机制事件来保存就应用程序状态和页面状态。利用这些状态,开发人员可以把应用程序恢复到最后一个正确的状态。你要了解一下以下两点:

  • 应用程序状态 是就应用程序的一种状态且并不与任何特定页面有关联。应用程序状态是在 PhoneApplicationService 类公开的事件中管理的。
  • 页面状态 是一种应用程序页面可见的状态。它包含了诸如 ScrollViewer 控件中滚轴的位置和 TextBox 控件 中的内容等信息。页面的状态管理应该由OnNavigatedTo 和 OnNavigatedFrom 事件处理程序来处理。

下面我们就针对上述所讲的,总结成一个DEMO吧:

首先我们在App.xaml文件中在针对的生命周期方法中键入代码,以下代码可供参考:

Application_Launching
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> private void Application_Launching( object sender,LaunchingEventArgse)
{
// Tracetheeventfordebugpurposes
Utils.Trace( " ApplicationLaunching " );

// Createnewdataobjectvariable
TravelReportInfotravelReportInfo = null ;

// 尝试从以前保存过的独立数据加载数据
using (IsolatedStorageFileisf = IsolatedStorageFile.GetUserStoreForApplication())
{
// 验证是否存在
if (isf.FileExists( " TravelReportInfo.dat " ))
{
using (IsolatedStorageFileStreamfs = isf.OpenFile( " TravelReportInfo.dat " ,System.IO.FileMode.Open))
{
// Readthefilecontentsandtrytodeserializeitbacktodataobject
XmlSerializerser = new XmlSerializer( typeof (TravelReportInfo));
object obj = ser.Deserialize(fs);

// 如果成功反序列化,则初始化变量
if ( null != obj && obj is TravelReportInfo)
travelReportInfo
= obj as TravelReportInfo;
else
travelReportInfo
= new TravelReportInfo();
}
}
else
// Ifpreviousdatanotfound,createnewinstance
travelReportInfo = new TravelReportInfo();
}

// 设置当前的数据上下文为tranvelInfo,页面启动完毕后我们就可以通过dataContext获取数据
RootFrame.DataContext = travelReportInfo;
}
Application_Activated
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> private void Application_Activated( object sender,ActivatedEventArgse)
{
// Tracetheeventfordebugpurposes
Utils.Trace( " ApplicationActivated " );

// Createnewdataobjectvariable
TravelReportInfotravelReportInfo = null ;

// 试着找出以前的数据状态
if (PhoneApplicationService.Current.State.ContainsKey( " UnsavedTravelReportInfo " ))
{
// 如果找到,则从中还原出来,并删除掉之前保存的状态
travelReportInfo = PhoneApplicationService.Current.State[ " UnsavedTravelReportInfo " ] as TravelReportInfo;

PhoneApplicationService.Current.State.Remove(
" UnsavedTravelReportInfo " );
}

// 因为应用可能会被逻辑删除,所以不能保证会被激活,如果程序被逻辑删除则创建新的数据
if ( null != travelReportInfo)
RootFrame.DataContext
= travelReportInfo;
else
RootFrame.DataContext
= new TravelReportInfo();
}
Application_Deactivated
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> private void Application_Deactivated( object sender,DeactivatedEventArgse)
{
// Tracetheeventfordebugpurposes
Utils.Trace( " ApplicationDeactivated " );

// 将当前的应用程序状态保存进数据中
PhoneApplicationService.Current.State.Add( " UnsavedTravelReportInfo " ,RootFrame.DataContext as TravelReportInfo);
}
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> private void Application_Closing( object sender,ClosingEventArgse)
{
// Tracetheeventfordebugpurposes
Utils.Trace( " ApplicationClosing " );
}

以上代码都做了注释了。

下面运行模拟器,查看一下日志的输出,ctrl+w+0:

当页面启动时:

导航进来时:

点击back,导航出去时:

点击下一页并点击BACK时:

注意:页面先进入第二页,并执行第二页的onNavigatedTo,然后点击BACK触发第二页的OnNavigatedFrom,之后再触发第一页的OnNavigatedOn。

在第一页的时候点击Start:

此时进入了应用程序生命周期的管理,执行失去激活事件。

最后,用户停留在应用程序菜单列单上,单击BACK按钮:

如图,应用程序执行了重新激活的事件,并执行了导航事件。

至此,生命周期课程学完了。觉得有一点跟ANDROID 差唱比较大的是,ANDROID是每个页面的生命周期,而Window Phone 7的页面是靠Navigated ,而整个应用程序的生命周期都归app.xaml处理,这是两者最大的不同吧。不知道将来WP7多任务会不会改变生命周期呢?呵呵。。

DEMO下载:Windows Phone 7生命周期

相关文章:

  • 你好,React setState
  • fastreport 如何 设置 richview 的 行高
  • Windows Phone 7 不温不火学习之《页面导航》
  • 我的ipad应用备份
  • 我又回来了
  • windows向ubuntu过渡之常用软件安装
  • java.util.ConcurrentModificationException 异常
  • windows和linux的协议栈驱动
  • vmware的vmnet-概念的解说
  • typeScript.webpackreact的正确版quickStart
  • vmware的vmnet-感官和视觉上的效果
  • 学习笔记:树分治
  • vmware的vmnet-有机会还要看源码
  • Python中递归的最大次数
  • vmware的vmnet-理解全景后解答两个问题
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Intervention/image 图片处理扩展包的安装和使用
  • leetcode46 Permutation 排列组合
  • PAT A1120
  • python docx文档转html页面
  • Spring Boot MyBatis配置多种数据库
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 解决iview多表头动态更改列元素发生的错误
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 开源SQL-on-Hadoop系统一览
  • 浅谈Golang中select的用法
  • 区块链共识机制优缺点对比都是什么
  • 使用agvtool更改app version/build
  • 提醒我喝水chrome插件开发指南
  • 线性表及其算法(java实现)
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • ${ }的特别功能
  • (6)设计一个TimeMap
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (分布式缓存)Redis哨兵
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (九)信息融合方式简介
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .Net程序帮助文档制作
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • .stream().map与.stream().flatMap的使用
  • /boot 内存空间不够
  • /etc/sudoer文件配置简析
  • @modelattribute注解用postman测试怎么传参_接口测试之问题挖掘
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [1]-基于图搜索的路径规划基础
  • [8481302]博弈论 斯坦福game theory stanford week 1