Windows Phone 8.1 應(yīng)用生命周期
一、“后退鍵”不會(huì)終止應(yīng)用
關(guān)于 Windows Phone 8.1 的應(yīng)用生命周期,***個(gè)要知道的關(guān)鍵就是:“后退鍵”不會(huì)終止應(yīng)用!
在 8.0 時(shí)代,不斷的按下“后退鍵”就可以完全的關(guān)閉并且終止應(yīng)用,但在 8.1 中,這樣的行為只會(huì)讓應(yīng)用處在 Suspended(掛起)狀態(tài),可以通過(guò)長(zhǎng)按“后退鍵”進(jìn)入多任務(wù)界面查看。
那如果還想像 8.0 一樣終止應(yīng)用呢?(雖然不推薦也沒(méi)有必要)可以在多任務(wù)界面點(diǎn)擊應(yīng)用右上角的“叉叉”或者向下滑。
二、應(yīng)用生命周期

應(yīng)用的三個(gè)狀態(tài)分別是:
A:NotRunning
也就是還沒(méi)開啟過(guò)應(yīng)用,在多任務(wù)界面沒(méi)有該應(yīng)用時(shí)。
B:Running
在屏幕上顯示的應(yīng)用就是 Running 狀態(tài),同時(shí)只會(huì)有 1 個(gè)應(yīng)用處于 Running 狀態(tài)。
C:Suspended
不在屏幕上顯示并能在多任務(wù)界面查看的應(yīng)用則處于 Suspended(掛起)狀態(tài)。
三種狀態(tài)間切換的操作:
(1)NotRunning -> Running
要從 NotRunning 切換到 Running 狀態(tài),其實(shí)也就是開啟應(yīng)用,可通過(guò)點(diǎn)擊應(yīng)用磁貼、應(yīng)用間協(xié)議啟動(dòng)、Cortana等方式。
在狀態(tài)的切換過(guò)程中會(huì)觸發(fā) OnLaunched 事件。
(2)Running -> Suspended
當(dāng)應(yīng)用不再占據(jù)屏幕時(shí)則從 Running 切換到 Suspended 狀態(tài),可以是“Win”鍵、“返回鍵”,有電話打來(lái)時(shí)也會(huì)掛起。
在狀態(tài)的切換過(guò)程中會(huì)觸發(fā) OnSuspending 事件。
(3)Suspended -> Running
如果在應(yīng)用掛起狀態(tài)時(shí)沒(méi)有因?yàn)槟承┰颍ū热鐑?nèi)存不足)導(dǎo)致應(yīng)用終止的話,點(diǎn)擊磁貼或者多任務(wù)切換都會(huì)讓應(yīng)用從 Suspender 返回到 Running 狀態(tài)。
在狀態(tài)的切換過(guò)程中會(huì)依次觸發(fā) OnResuming 和 OnLaunched 事件。
(4)Suspended -> NotRunning
如果在應(yīng)用掛起狀態(tài)時(shí)因?yàn)槟承┰颍ū热鐑?nèi)存不足)導(dǎo)致應(yīng)用終止的話,則會(huì)從 Suspended 變成 NotRunning 狀態(tài)。
在這過(guò)程不會(huì)觸發(fā)任何事件。
#p#
三、OnSuspending
因?yàn)閼?yīng)用在掛起狀態(tài)時(shí),并不能預(yù)測(cè)應(yīng)用是否會(huì)因?yàn)槟承┰颍ū热鐑?nèi)存不足)而終止,而在這終止過(guò)程中也沒(méi)有事件讓開發(fā)者處理應(yīng)用數(shù)據(jù),所以只能在應(yīng)用將要掛起時(shí)準(zhǔn)備。因此 OnSuspending 事件變得十分重要。
若要使用 OnSuspending 方法則先要在構(gòu)造函數(shù)中添加對(duì)其的引用:
- public App()
 - {
 - this.InitializeComponent();
 - this.Suspending += OnSuspending;
 
而在 OnSuspending 方法中可以根據(jù)需要保存頁(yè)面數(shù)據(jù),比如輸入框內(nèi)的文本、頁(yè)面導(dǎo)航歷史等,可以通過(guò)保存在應(yīng)用獨(dú)立存儲(chǔ)中或利用 NavigationHelper 和 SuspensionManager 類等:
- async void OnSuspending(object sender, SuspendingEventArgs e)
 - {
 - SuspendingDeferral deferral = e.SuspendingOperation.GetDeferral();
 - await this.SaveStateToLocalFile(Data.Value);
 - await SuspensionManager.SaveAsync();
 - deferral.Complete();
 如果只想保存某個(gè)頁(yè)面的信息則可以在 SaveState 中保存
- private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
 - {
 - e.PageState["isEditing"] = true;
 - e.PageState["currentText"] = this.viewModel.DataItem.Title;
 - }
 NavigationHelper 和 SuspensionManager 類是添加基本頁(yè)時(shí) Visual Studio 自動(dòng)添加的
#p#
- public class NavigationHelper : DependencyObject
 - {
 - private Page Page { get; set; }
 - private Frame Frame { get { return this.Page.Frame; } }
 - public NavigationHelper(Page page)
 - {
 - this.Page = page;
 - this.Page.Loaded += (sender, e) =>
 - {
 - WINDOWS_PHONE_APP
 - Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
 - e
 - if
 - };
 - this.Page.Unloaded += (sender, e) =>
 - {
 - WINDOWS_PHONE_APP
 - Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
 - e
 - if
 - };
 - }
 - #region Navigation support
 - RelayCommand _goBackCommand;
 - RelayCommand _goForwardCommand;
 - public RelayCommand GoBackCommand
 - {
 - get
 - {
 - if (_goBackCommand == null)
 - {
 - _goBackCommand = new RelayCommand(
 - () => this.GoBack(),
 - () => this.CanGoBack());
 - }
 - return _goBackCommand;
 - }
 - set
 - {
 - _goBackCommand = value;
 - }
 - }
 - public RelayCommand GoForwardCommand
 - {
 - get
 - {
 - if (_goForwardCommand == null)
 - {
 - _goForwardCommand = new RelayCommand(
 - () => this.GoForward(),
 - () => this.CanGoForward());
 - }
 - return _goForwardCommand;
 - }
 - }
 - public virtual bool CanGoBack()
 - {
 - return this.Frame != null && this.Frame.CanGoBack;
 - }
 - public virtual bool CanGoForward()
 - {
 - return this.Frame != null && this.Frame.CanGoForward;
 - }
 - public virtual void GoBack()
 - {
 - if (this.Frame != null && this.Frame.CanGoBack) this.Frame.GoBack();
 - }
 - public virtual void GoForward()
 - {
 - if (this.Frame != null && this.Frame.CanGoForward) this.Frame.GoForward();
 - }
 - #if WINDOWS_PHONE_APP
 - private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
 - {
 - if (this.GoBackCommand.CanExecute(null))
 - {
 - e.Handled = true;
 - this.GoBackCommand.Execute(null);
 - }
 - }
 - #else
 - private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender,
 - AcceleratorKeyEventArgs e)
 - {
 - var virtualKey = e.VirtualKey;
 - if ((e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown ||
 - e.EventType == CoreAcceleratorKeyEventType.KeyDown) &&
 - (virtualKey == VirtualKey.Left || virtualKey == VirtualKey.Right ||
 - (int)virtualKey == 166 || (int)virtualKey == 167))
 - {
 - var coreWindow = Window.Current.CoreWindow;
 - var downState = CoreVirtualKeyStates.Down;
 - bool menuKey = (coreWindow.GetKeyState(VirtualKey.Menu) & downState) == downState;
 - bool controlKey = (coreWindow.GetKeyState(VirtualKey.Control) & downState) == downState;
 - bool shiftKey = (coreWindow.GetKeyState(VirtualKey.Shift) & downState) == downState;
 - bool noModifiers = !menuKey && !controlKey && !shiftKey;
 - bool onlyAlt = menuKey && !controlKey && !shiftKey;
 - if (((int)virtualKey == 166 && noModifiers) ||
 - (virtualKey == VirtualKey.Left && onlyAlt))
 - {
 - e.Handled = true;
 - this.GoBackCommand.Execute(null);
 - }
 - else if (((int)virtualKey == 167 && noModifiers) ||
 - (virtualKey == VirtualKey.Right && onlyAlt))
 - {
 - e.Handled = true;
 - this.GoForwardCommand.Execute(null);
 - }
 - }
 - }
 - private void CoreWindow_PointerPressed(CoreWindow sender,
 - PointerEventArgs e)
 - {
 - var properties = e.CurrentPoint.Properties;
 - if (properties.IsLeftButtonPressed || properties.IsRightButtonPressed ||
 - properties.IsMiddleButtonPressed) return;
 - bool backPressed = properties.IsXButton1Pressed;
 - bool forwardPressed = properties.IsXButton2Pressed;
 - if (backPressed ^ forwardPressed)
 - {
 - e.Handled = true;
 - if (backPressed) this.GoBackCommand.Execute(null);
 - if (forwardPressed) this.GoForwardCommand.Execute(null);
 - }
 - }
 - #endif
 - #endregion
 - #region Process lifetime management
 - private String _pageKey;
 - public event LoadStateEventHandler LoadState;
 - public event SaveStateEventHandler SaveState;
 - public void OnNavigatedTo(NavigationEventArgs e)
 - {
 - var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
 - this._pageKey = "Page-" + this.Frame.BackStackDepth;
 - if (e.NavigationMode == NavigationMode.New)
 - {
 - var nextPageKey = this._pageKey;
 - int nextPageIndex = this.Frame.BackStackDepth;
 - while (frameState.Remove(nextPageKey))
 - {
 - nextPageIndex++;
 - nextPageKey = "Page-" + nextPageIndex;
 - }
 - if (this.LoadState != null)
 - {
 - this.LoadState(this, new LoadStateEventArgs(e.Parameter, null));
 - }
 - }
 - else
 - {
 - if (this.LoadState != null)
 - {
 - this.LoadState(this, new LoadStateEventArgs(e.Parameter, (Dictionary<String, Object>)frameState[this._pageKey]));
 - }
 - }
 - }
 - public void OnNavigatedFrom(NavigationEventArgs e)
 - {
 - var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
 - var pageState = new Dictionary<String, Object>();
 - if (this.SaveState != null)
 - {
 - this.SaveState(this, new SaveStateEventArgs(pageState));
 - }
 - frameState[_pageKey] = pageState;
 - }
 - #endregion
 - }
 - public delegate void LoadStateEventHandler(object sender, LoadStateEventArgs e);
 - public delegate void SaveStateEventHandler(object sender, SaveStateEventArgs e);
 - public class LoadStateEventArgs : EventArgs
 - {
 - public Object NavigationParameter { get; private set; }
 - public Dictionary<string, Object> PageState { get; private set; }
 - public LoadStateEventArgs(Object navigationParameter, Dictionary<string, Object> pageState)
 - : base()
 - {
 - this.NavigationParameter = navigationParameter;
 - this.PageState = pageState;
 - }
 - }
 - public class SaveStateEventArgs : EventArgs
 - {
 - public Dictionary<string, Object> PageState { get; private set; }
 - public SaveStateEventArgs(Dictionary<string, Object> pageState)
 - : base()
 - {
 - this.PageState = pageState;
 - }
 - }
 
四、OnResuming
既然在 OnSuspending 和 SaveState 方法中保存了必要數(shù)據(jù),就可以在 OnResuming 和 LoadState 方法中獲取之前保存的數(shù)據(jù)
- void OnResuming(object sender, object e)
 - {
 - Data.Value += this.CalculateOffsetTimeInDecimalSeconds(this.suspensionTime);
 - }
 
- private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
 - {
 - if ((e.PageState != null) && e.PageState.ContainsKey("isEditing"))
 - {
 - this.viewModel.SetEditMode();
 - this.viewModel.DataItem.Title = e.PageState["currentText"] as string;
 - }
 - }
 
五、OnLaunched
首先,在 OnLaunched 方法中可以通過(guò) e.PreviousExecutionState 了解到應(yīng)用之前的狀態(tài)。
狀態(tài)包括:
(1)CloseByUser:被用戶主動(dòng)在多任務(wù)界面中關(guān)閉
(2)NotRunning:沒(méi)有啟動(dòng)過(guò)
(3)Running:?jiǎn)?dòng)中
(4)Terminated:掛起狀態(tài)時(shí)因內(nèi)存不足被系統(tǒng)終止
(5)Suspended:掛起狀態(tài)
因此,可以通過(guò)對(duì)此的判斷,根據(jù)不同情況處理應(yīng)用:
- protected async override void OnLaunched(LaunchActivatedEventArgs e)
 - {
 - Frame rootFrame = Window.Current.Content as Frame;
 - if (rootFrame == null)
 - {
 - rootFrame = new Frame();
 - SuspensionManager.RegisterFrame(rootFrame, "AppFrame");
 - rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];
 - if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
 - {
 - try
 - {
 - await SuspensionManager.RestoreAsync();
 - }
 - catch (SuspensionManagerException)
 - {
 - }
 - }
 - Window.Current.Content = rootFrame;
 - }
 - if (rootFrame.Content == null)
 - {
 - rootFrame.Navigate(typeof(MainPage), e.Arguments);
 - }
 - Window.Current.Activate();
 - }
 
六、注意
以上的方法盡量使用異步操作,不要進(jìn)行大量的復(fù)雜操作
本文鏈接:http://www.cnblogs.com/xiaoshi3003/p/3752895.html















 
 
 



 
 
 
 