Windows Phone 8.1 应用生命周期

移动开发
在 8.0 时代,不断的按下“后退键”就可以完全的关闭并且终止应用,但在 8.1 中,这样的行为只会让应用处在 Suspended(挂起)状态,可以通过长按“后退键”进入多任务界面查看。 那如果还想像 8.0 一样终止应用呢?(虽然不推荐也没有必要)可以在多任务界面点击应用右上角的“叉叉”或者向下滑。

一、“后退键”不会终止应用

关于 Windows Phone 8.1 的应用生命周期,***个要知道的关键就是:“后退键”不会终止应用!

在 8.0 时代,不断的按下“后退键”就可以完全的关闭并且终止应用,但在 8.1 中,这样的行为只会让应用处在 Suspended(挂起)状态,可以通过长按“后退键”进入多任务界面查看。

那如果还想像 8.0 一样终止应用呢?(虽然不推荐也没有必要)可以在多任务界面点击应用右上角的“叉叉”或者向下滑。

 

二、应用生命周期

应用的三个状态分别是:

A:NotRunning

也就是还没开启过应用,在多任务界面没有该应用时。

B:Running

在屏幕上显示的应用就是 Running 状态,同时只会有 1 个应用处于 Running 状态。

C:Suspended

不在屏幕上显示并能在多任务界面查看的应用则处于 Suspended(挂起)状态。

 

三种状态间切换的操作:

(1)NotRunning -> Running

要从 NotRunning 切换到 Running 状态,其实也就是开启应用,可通过点击应用磁贴、应用间协议启动、Cortana等方式。

在状态的切换过程中会触发 OnLaunched 事件。

(2)Running -> Suspended

当应用不再占据屏幕时则从 Running 切换到 Suspended 状态,可以是“Win”键、“返回键”,有电话打来时也会挂起。

在状态的切换过程中会触发 OnSuspending 事件。

(3)Suspended -> Running

如果在应用挂起状态时没有因为某些原因(比如内存不足)导致应用终止的话,点击磁贴或者多任务切换都会让应用从 Suspender 返回到 Running 状态。

在状态的切换过程中会依次触发 OnResuming 和 OnLaunched 事件。

(4)Suspended -> NotRunning

如果在应用挂起状态时因为某些原因(比如内存不足)导致应用终止的话,则会从 Suspended 变成 NotRunning 状态。

在这过程不会触发任何事件。

 #p#

三、OnSuspending

因为应用在挂起状态时,并不能预测应用是否会因为某些原因(比如内存不足)而终止,而在这终止过程中也没有事件让开发者处理应用数据,所以只能在应用将要挂起时准备。因此 OnSuspending 事件变得十分重要。

若要使用 OnSuspending 方法则先要在构造函数中添加对其的引用:

  1. public App() 
  2.   this.InitializeComponent(); 
  3.   this.Suspending += OnSuspending; 
而在 OnSuspending 方法中可以根据需要保存页面数据,比如输入框内的文本、页面导航历史等,可以通过保存在应用独立存储中或利用 NavigationHelper 和 SuspensionManager 类等:
  1. async void OnSuspending(object sender, SuspendingEventArgs e) 
  2.     SuspendingDeferral deferral = e.SuspendingOperation.GetDeferral(); 
  3.  
  4.     await this.SaveStateToLocalFile(Data.Value); 
  5.  
  6. await SuspensionManager.SaveAsync(); 
  7.  deferral.Complete();

如果只想保存某个页面的信息则可以在 SaveState 中保存

  1. private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e) 
  2.      e.PageState["isEditing"] = true
  3.      e.PageState["currentText"] = this.viewModel.DataItem.Title; 

NavigationHelper 和 SuspensionManager 类是添加基本页时 Visual Studio 自动添加的

  1. public class NavigationHelper : DependencyObject 
  2.     private Page Page { get; set; } 
  3.     private Frame Frame { get { return this.Page.Frame; } } 
  4.  
  5.     public NavigationHelper(Page page) 
  6.     { 
  7.         this.Page = page; 
  8.  
  9.         this.Page.Loaded += (sender, e) => 
  10.         { 
  11. WINDOWS_PHONE_APP 
  12.             Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed; 
  13.  
  14. if 
  15.         }; 
  16.  
  17.         this.Page.Unloaded += (sender, e) => 
  18.         { 
  19. WINDOWS_PHONE_APP 
  20.             Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed; 
  21.  
  22. if 
  23.         }; 
  24.     } 
  25.  
  26.     #region Navigation support 
  27.  
  28.         RelayCommand _goBackCommand; 
  29.         RelayCommand _goForwardCommand; 
  30.  
  31.         public RelayCommand GoBackCommand 
  32.         { 
  33.             get 
  34.             { 
  35.                 if (_goBackCommand == null
  36.                 { 
  37.                     _goBackCommand = new RelayCommand( 
  38.                         () => this.GoBack(), 
  39.                         () => this.CanGoBack()); 
  40.                 } 
  41.                 return _goBackCommand; 
  42.             } 
  43.             set 
  44.             { 
  45.                 _goBackCommand = value; 
  46.             } 
  47.         } 
  48.  
  49.         public RelayCommand GoForwardCommand 
  50.         { 
  51.             get 
  52.             { 
  53.                 if (_goForwardCommand == null
  54.                 { 
  55.                     _goForwardCommand = new RelayCommand( 
  56.                         () => this.GoForward(), 
  57.                         () => this.CanGoForward()); 
  58.                 } 
  59.                 return _goForwardCommand; 
  60.             } 
  61.         } 
  62.  
  63.         public virtual bool CanGoBack() 
  64.         { 
  65.             return this.Frame != null && this.Frame.CanGoBack; 
  66.         } 
  67.  
  68.         public virtual bool CanGoForward() 
  69.         { 
  70.             return this.Frame != null && this.Frame.CanGoForward; 
  71.         } 
  72.  
  73.         public virtual void GoBack() 
  74.         { 
  75.             if (this.Frame != null && this.Frame.CanGoBack) this.Frame.GoBack(); 
  76.         } 
  77.  
  78.         public virtual void GoForward() 
  79.         { 
  80.             if (this.Frame != null && this.Frame.CanGoForward) this.Frame.GoForward(); 
  81.         } 
  82.  
  83. #if WINDOWS_PHONE_APP 
  84.         private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e) 
  85.         { 
  86.             if (this.GoBackCommand.CanExecute(null)) 
  87.             { 
  88.                 e.Handled = true
  89.                 this.GoBackCommand.Execute(null); 
  90.             } 
  91.         } 
  92. #else 
  93.         private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender, 
  94.             AcceleratorKeyEventArgs e) 
  95.         { 
  96.             var virtualKey = e.VirtualKey; 
  97.  
  98.             if ((e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown || 
  99.                 e.EventType == CoreAcceleratorKeyEventType.KeyDown) && 
  100.                 (virtualKey == VirtualKey.Left || virtualKey == VirtualKey.Right || 
  101.                 (int)virtualKey == 166 || (int)virtualKey == 167)) 
  102.             { 
  103.                 var coreWindow = Window.Current.CoreWindow; 
  104.                 var downState = CoreVirtualKeyStates.Down; 
  105.                 bool menuKey = (coreWindow.GetKeyState(VirtualKey.Menu) & downState) == downState; 
  106.                 bool controlKey = (coreWindow.GetKeyState(VirtualKey.Control) & downState) == downState; 
  107.                 bool shiftKey = (coreWindow.GetKeyState(VirtualKey.Shift) & downState) == downState; 
  108.                 bool noModifiers = !menuKey && !controlKey && !shiftKey; 
  109.                 bool onlyAlt = menuKey && !controlKey && !shiftKey; 
  110.  
  111.                 if (((int)virtualKey == 166 && noModifiers) || 
  112.                     (virtualKey == VirtualKey.Left && onlyAlt)) 
  113.                 { 
  114.                     e.Handled = true
  115.                     this.GoBackCommand.Execute(null); 
  116.                 } 
  117.                 else if (((int)virtualKey == 167 && noModifiers) || 
  118.                     (virtualKey == VirtualKey.Right && onlyAlt)) 
  119.                 { 
  120.                     e.Handled = true
  121.                     this.GoForwardCommand.Execute(null); 
  122.                 } 
  123.             } 
  124.         } 
  125.  
  126.         private void CoreWindow_PointerPressed(CoreWindow sender, 
  127.             PointerEventArgs e) 
  128.         { 
  129.             var properties = e.CurrentPoint.Properties; 
  130.  
  131.             if (properties.IsLeftButtonPressed || properties.IsRightButtonPressed || 
  132.                 properties.IsMiddleButtonPressed) return
  133.  
  134.             bool backPressed = properties.IsXButton1Pressed; 
  135.             bool forwardPressed = properties.IsXButton2Pressed; 
  136.             if (backPressed ^ forwardPressed) 
  137.             { 
  138.                 e.Handled = true
  139.                 if (backPressed) this.GoBackCommand.Execute(null); 
  140.                 if (forwardPressed) this.GoForwardCommand.Execute(null); 
  141.             } 
  142.         } 
  143. #endif 
  144.  
  145.         #endregion 
  146.  
  147.     #region Process lifetime management 
  148.  
  149.         private String _pageKey; 
  150.         public event LoadStateEventHandler LoadState; 
  151.         public event SaveStateEventHandler SaveState; 
  152.  
  153.         public void OnNavigatedTo(NavigationEventArgs e) 
  154.         { 
  155.             var frameState = SuspensionManager.SessionStateForFrame(this.Frame); 
  156.             this._pageKey = "Page-" + this.Frame.BackStackDepth; 
  157.  
  158.             if (e.NavigationMode == NavigationMode.New) 
  159.             { 
  160.                 var nextPageKey = this._pageKey; 
  161.                 int nextPageIndex = this.Frame.BackStackDepth; 
  162.                 while (frameState.Remove(nextPageKey)) 
  163.                 { 
  164.                     nextPageIndex++; 
  165.                     nextPageKey = "Page-" + nextPageIndex; 
  166.                 } 
  167.  
  168.                 if (this.LoadState != null
  169.                 { 
  170.                     this.LoadState(thisnew LoadStateEventArgs(e.Parameter, null)); 
  171.                 } 
  172.             } 
  173.             else 
  174.             { 
  175.                 if (this.LoadState != null
  176.                 { 
  177.                     this.LoadState(thisnew LoadStateEventArgs(e.Parameter, (Dictionary<String, Object>)frameState[this._pageKey])); 
  178.                 } 
  179.             } 
  180.         } 
  181.  
  182.         public void OnNavigatedFrom(NavigationEventArgs e) 
  183.         { 
  184.             var frameState = SuspensionManager.SessionStateForFrame(this.Frame); 
  185.             var pageState = new Dictionary<String, Object>(); 
  186.             if (this.SaveState != null
  187.             { 
  188.                 this.SaveState(thisnew SaveStateEventArgs(pageState)); 
  189.             } 
  190.             frameState[_pageKey] = pageState; 
  191.         } 
  192.  
  193.         #endregion 
  194.  
  195.  
  196. public delegate void LoadStateEventHandler(object sender, LoadStateEventArgs e); 
  197. public delegate void SaveStateEventHandler(object sender, SaveStateEventArgs e); 
  198.  
  199. public class LoadStateEventArgs : EventArgs 
  200.     public Object NavigationParameter { get; private set; } 
  201.     public Dictionary<string, Object> PageState { get; private set; } 
  202.  
  203.     public LoadStateEventArgs(Object navigationParameter, Dictionary<string, Object> pageState) 
  204.         : base() 
  205.     { 
  206.         this.NavigationParameter = navigationParameter; 
  207.         this.PageState = pageState; 
  208.     } 
  209.  
  210. public class SaveStateEventArgs : EventArgs 
  211.     public Dictionary<string, Object> PageState { get; private set; } 
  212.     public SaveStateEventArgs(Dictionary<string, Object> pageState) 
  213.         : base() 
  214.     { 
  215.         this.PageState = pageState; 
  216.     } 
#p#

四、OnResuming

既然在 OnSuspending 和 SaveState 方法中保存了必要数据,就可以在 OnResuming 和 LoadState 方法中获取之前保存的数据

  1. void OnResuming(object sender, object e) 
  2.     Data.Value += this.CalculateOffsetTimeInDecimalSeconds(this.suspensionTime); 
  1. private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) 
  2.     if ((e.PageState != null) && e.PageState.ContainsKey("isEditing")) 
  3.     { 
  4.         this.viewModel.SetEditMode(); 
  5.         this.viewModel.DataItem.Title = e.PageState["currentText"] as string; 
  6.     } 

五、OnLaunched

首先,在 OnLaunched 方法中可以通过 e.PreviousExecutionState 了解到应用之前的状态。

状态包括:

(1)CloseByUser:被用户主动在多任务界面中关闭

(2)NotRunning:没有启动过

(3)Running:启动中

(4)Terminated:挂起状态时因内存不足被系统终止

(5)Suspended:挂起状态

因此,可以通过对此的判断,根据不同情况处理应用:

  1. protected async override void OnLaunched(LaunchActivatedEventArgs e) 
  2.   Frame rootFrame = Window.Current.Content as Frame; 
  3.  
  4.   if (rootFrame == null
  5.   { 
  6.     rootFrame = new Frame(); 
  7.  
  8.     SuspensionManager.RegisterFrame(rootFrame, "AppFrame"); 
  9.  
  10.     rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0]; 
  11.  
  12.     if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 
  13.     { 
  14.       try 
  15.       { 
  16.         await SuspensionManager.RestoreAsync(); 
  17.       } 
  18.       catch (SuspensionManagerException) 
  19.       { 
  20.       } 
  21.     } 
  22.  
  23.     Window.Current.Content = rootFrame; 
  24.   } 
  25.  
  26.   if (rootFrame.Content == null
  27.   { 
  28.     rootFrame.Navigate(typeof(MainPage), e.Arguments); 
  29.   } 
  30.  
  31.   Window.Current.Activate(); 

六、注意

以上的方法尽量使用异步操作,不要进行大量的复杂操作

 本文链接:http://www.cnblogs.com/xiaoshi3003/p/3752895.html

责任编辑:chenqingxiang 来源: cnblogs
相关推荐

2013-07-31 14:50:32

Windows PhoWP应用程序生命周期

2012-05-28 15:37:20

WP程序生命周期

2013-08-01 09:40:51

Windows 8.1

2012-06-20 10:29:16

敏捷开发

2013-12-13 09:47:23

2015-07-09 15:42:48

ios应用生命周期

2011-07-20 15:58:58

iPhone 应用程序 生命周期

2009-06-24 10:34:39

JSF生命周期JSF应用程序

2015-07-08 16:28:23

weak生命周期

2023-04-19 07:50:59

​云原生生命周期管理

2011-08-10 16:50:10

iPhone生命周期

2014-07-11 11:09:10

App应用程序生命周期

2012-12-04 10:02:03

2013-09-26 11:20:34

Informatica

2022-04-19 07:20:24

软件开发安全生命周期SSDLC应用安全

2021-07-19 05:52:29

网络生命周期网络框架

2013-08-19 17:03:00

.Net生命周期对象

2009-06-24 10:47:55

JSF生命周期

2010-07-14 10:48:37

Perl线程

2009-06-11 11:28:35

JSF生命周期
点赞
收藏

51CTO技术栈公众号