windows phone7 学习笔记10——生命周期/墓碑化

  WP7应用程序的生命周期指的是一个应用程序在启动、关闭、墓碑化、休眠(7.1更新)或运行中的各种状态和他们之间的关系。其中休眠是7.1更新的,在这边文章中不考虑。

  在Windows Phone上运行的应用程序从开始到程序运行结束,其整个生命周期都是由Windows phone的执行模型所支配。执行模型被设计的目的就是为终端用户实时提供快速的、反应灵敏的体验。为了实现这样的初衷,Windows Phone仅仅允许在前台运行一个第三方应用程序(7.0中)——即与用户进行交互的可见的当前应用程序。这样做就消除了用户在其移动终端设备后台上运行多个应用程序而导致的程序间竞争有限的系统资源,而使用户的移动终端设备处于较低的性能和电池电量急剧减少的可能性。

  在生命周期中,下面的几个事件是非常重要到:

  App.xaml.cs:Application_Launching 

  App.xaml.cs:Application_Closing

  App.xaml.cs:Application_Deactivated

  App.xaml.cs:Application_Activated

  Page.cs:OnNavigatedFrom:离开当前页面时(不要弄反了)

  Page.cs:OnNavigatedTo:进入当前页面时


  1、一般生命周期

  这里说的一般生命周期指的是没有被中断的生命周期,经历了程序启动(Application_Launching)——进入主页面(OnNavigatedTo)——离开主页面(OnNavigationFrom)——程序直接通过BACK键关闭(Application_Closing)

  

  1、应用程序第一次启动(首页Tile或应用列表中启动)就开启一个进程,产生应用程序实例,然后就调用Launching事件,在这里你可以做一些程序初始化的准备工作,但不要做太耗时的工作,比如读取文件或者说是调用服务器端数据等,因为在这里页面还没有加载,避免用户误以为软件Bug或是其他异常。还有就是微软的10s规则,如果在10s还没有启动,系统将会直接关闭程序。

  2、第一个界面出来了,进入Running状态。如果你按下return按钮,会引发回退,因为它前面已经没有页面回退,因此它会引发了Closeing事件,关闭程序。

  这个过程触发了四个事件:依次是:Launching、OnNavigatedTo、OnNavigatedFrom、Closing。

  2、墓碑化(TombStone)生命周期

  程序被中断(包括屏幕锁、呼入电话、短信息、提醒功能、低电量、程序切换、用户点击开始按钮等),进入墓碑化状态的生命周期,经历了程序启动(Application_Launching)----进入主页面(OnNavigatedTo)----离开主页面(OnNavigationFrom)----进入墓碑状态(Application_Deactivated)----从墓碑中恢复(Application_Activated)----进入主页面(OnNavigatedTo)----离开主页面(OnNavigationFrom)----程序直接通过BACK键关闭(Application_Closing)。

  

  注意:并不是所有的应用程序进入墓碑化之后都会被Activated。比如用户运行程序时点击开始按钮进入墓碑化状态,但是又从程序列表或者开始界面点击程序图标进入程序,此时并不调用Activated事件,而是直接启动,调用Launching,产生一个新的应用程序实例。只有当用户完成其他的任务,通过back按钮返回应用程序,才会Activated。


  代码示例

  app.xaml.cs

        private void Application_Launching(object sender, LaunchingEventArgs e)
{
Debug.WriteLine("TOMBSTONE:Application_Launching at {0}" + DateTime.Now.ToLongTimeString());
}

// 激活应用程序(置于前台)时执行的代码
// 此代码在首次启动应用程序时不执行
private void Application_Activated(object sender, ActivatedEventArgs e)
{
Debug.WriteLine("TOMBSTONE:Application_Activated at {0}" + DateTime.Now.ToLongTimeString());
}

// 停用应用程序(发送到后台)时执行的代码
// 此代码在应用程序关闭时不执行
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
Debug.WriteLine("TOMBSTONE:Application_Deactivated at {0}" + DateTime.Now.ToLongTimeString());
}

// 应用程序关闭(例如,用户点击“后退”)时执行的代码
// 此代码在停用应用程序时不执行
private void Application_Closing(object sender, ClosingEventArgs e)
{
Debug.WriteLine("TOMBSTONE:Application_Closing at {0}" + DateTime.Now.ToLongTimeString());
}

  MainPage.xaml.cs

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
Debug.WriteLine("TOMBSTONE:OnNavigatedTo at {0}" + DateTime.Now.ToLongTimeString());
}

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Debug.WriteLine("TOMBSTONE:OnNavigatedFrom at {0}" + DateTime.Now.ToLongTimeString());
}


  输出结果:

TOMBSTONE:Application_Launching at {0}21:47:49
TOMBSTONE:OnNavigatedTo at {0}21:47:49
TOMBSTONE:OnNavigatedFrom at {0}21:48:45
“UI Task”(托管): 已加载“System.Runtime.Serialization.dll”
TOMBSTONE:Application_Deactivated at {0}21:48:46
TOMBSTONE:Application_Activated at {0}21:49:01
TOMBSTONE:OnNavigatedTo at {0}21:49:01
TOMBSTONE:OnNavigatedFrom at {0}21:49:18
TOMBSTONE:Application_Closing at {0}21:49:18


  现在我们再重新看看那六个事件,每个事件应该做哪些工作:

  (1)Launching:行非常少量的代码,不要执行资源密集型操作,一般为从Isolated Storage中加载一些永久配置数据(persisted data)。应用程序不应该试图从以前的应用程 序实例中恢复瞬时状态。当用户启动一个应用程序,就出现了一个新的应用程序实例。

      using (IsolatedStorageFile Iso = IsolatedStorageFile.GetUserStoreForApplication())
{
if(IsolatedStorageSettings.ApplicationSettings.Contains(IsoSetting1))
{
IsoContext = IsolatedStorageSettings.ApplicationSettings[IsoSetting1] as string;
}
}


  (2)Closing: 处理关闭事件,应用程序应该把所有的持久化数据保存到独立的存储中。此时没有必要保存瞬时状态数据,即那些只和前应用程序实例相关的数据。

            using (IsolatedStorageFile Iso = IsolatedStorageFile.GetUserStoreForApplication())
{
IsolatedStorageSettings.ApplicationSettings[IsoSetting1] = IsoContext;
}


  (3)Deactivated:使用PhoneApplicationService.State保存一些临时数据(transient data)。 在状态信息词典中存储的数据是瞬时状态数据或者是能帮助应用程序在被禁止时恢复其状态的数据。由于并不能保证一个被禁止的应用程序会被重新激活,所以在此事件的处理中应用程序需要把永久配置数据保存到独立存储空间。

PhoneApplicationService.Current.State[IsoSetting1] = IsoContext;


  (4)Activated:从PhoneApplicationService.State读取一些临时数据,恢复到用户离开此页面的状态,保持用户体验的一致性。

IsoContext = PhoneApplicationService.Current.State[IsoSetting1] as string;


  (5)OnNavigatedFrom保存一些页面级的信息,使用PhoneApplicationPage.State来保存信息。

            base.OnNavigatedFrom(e);
if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
{
State[numsetting1] = num;
}


  (6)OnNavigatedFTo:PhoneApplicationPage.State中读取数据,回复页面状态,让用户看到和原先一摸一样的页面(包括光标位置、ScrollViewer的位置、DeepZoom的图片大小)。

            base.OnNavigatedTo(e);
if (e.NavigationMode != System.Windows.Navigation.NavigationMode.New)
{
if (State.ContainsKey(numsetting))
{
num = State[numsetting] as string;
}
}


  最后总结下整个生命周期:

  

  

  

  补充:休眠(Dormant)

  休眠是在7.1之后加进去的,也就是所谓的伪多任务。

  当用户向前导航或导航出应用程序时,引发 Deactivated 事件后,操作系统将尝试使应用程序置于休眠状态。在此状态下,应用程序的所有线程均将停止,并且不进行任何处理操作,但应用程序仍完好地保留在内存中。如果从该状态中重新激活应用程序,应用程序无需重新创建任何状态,因为状态已保留。

  如果在应用程序进入休眠状态后启动新的应用程序,这些应用程序需要更多的内存才能提供出色的用户体验,操作系统将开始逻辑删除休眠的应用程序以释放内存。

  休眠和墓碑化的区别(个人理解,仅供参考):休眠是将所有应用程序信息保留在内存中,当用户恢复程序时,就不需要创建一个新的实例。而墓碑化的应用程序是穿件了一个新的实例,然后从PhoneApplicationService.State中加载原来的信息,使应用程序看上去和原来一样。


  参考文章:http://www.devdiv.com/forum.php?mod=viewthread&tid=83033&extra=page%3D1%26filter%3Dtypeid%26typeid%3D305%26typeid%3D305

       http://www.cnblogs.com/zhangdongzi/archive/2011/08/24/2152551.html

       http://www.cnblogs.com/konck/archive/2012/01/14/2322245.html

       http://msdn.microsoft.com/zh-cn/library/ff817008(v=VS.92).aspx

   还有一个Idle detection问题,可以看这篇文章的后半部分:http://msdn.microsoft.com/zh-cn/windowsphone/gg546046.aspx


原文地址:https://www.cnblogs.com/zhangkai2237/p/2357661.html