今天在做項目時,意識到Win8 Meto App也有“墓碑”這個概念。從以下場景可以看出:從首頁登錄頁面登錄,進行列表頁面,此時按Win鍵返加桌面開啟另外一個應用程序,當我再次返回我第一個頁面時,卻顯示的是登錄頁面,這與想象的場景是不相符合的,做過Windows Phonen7的同胞應該都知道,在wp7 7.0的時是有“墓碑”的機制的,與以上場景完全類似。
不得不先學習一下Windows 8應用程序的生命周期啦,參照http://blogs.msdn.com/b/windowsappdev_cn/archive/2012/04/16/managing-app-lifecycle.aspx的博文進行學習的~
生命周期的狀態
在Metro風格應用程序有四種狀態:未運行、正在運行、已掛起或已終止。這些狀態都會對應相應的事件,我們可以都過捕獲這些事件做邏輯處理。
生命周期的相關事件
OnLaunched 程序開啟事件
場景:第一次程序開啟時會執行
OnSuspending 程序掛起事件
場景:在程序開啟時,按win鍵或切換到其它應用程序,當前程序會處於掛起狀態,大概測了一下,程序會在1分左右才會掛起,不會立即掛起
在該事件中,可以保存一些應用數據,以便在恢復時可以顯示上一次瀏覽的頁面及相應的數據
Resuming 當掛起狀態恢復到程序運行時觸發的事件
場景:當重新切換當前程序時,會執行,可以判斷相關的數據是否保存,從而進行相應的顯示
OnActivated 當應用程序不是普通的啟動,而是通過其它途徑被調用啟動時觸發
場景:該場景暫時還沒有試驗
生命周期狀態分析
掛起
當用戶切換到另一應用程序時當前程序停止運行。Windows會掛起不在前台的應用程序,程序需注冊Suspending事件,當前應用程序離開前台時,我測了一下(不知與個人機器有無關系),在1分左右的時間后程序才會掛起。在該事件中,保存必須持久存儲的相關數據。
首先在APP()構造函數中,注冊Suspending事件
this.Suspending += OnSuspending; void OnSuspending(object sender, SuspendingEventArgs e) { SuspendingDeferral deferral = e.SuspendingOperation.GetDeferral(); var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; localSettings.Values["currentpage"] = MemoryData.CurrentPage; deferral.Complete(); }
恢復
當重新回到應用程序時,應用程序狀態將從掛起狀態轉成恢復狀態,在注冊Resuming事件后,應用程序中的數據將恢復到當時扶起時的數據。
這就是我們要實現“墓碑”的關鍵所在了,當程序恢復時,當前的數據應該至少與上一次看的相同,若更為真切地感覺程序處於運行狀態,應該顯示最新的數據,可以利用掛起時的數據獲取更新的數據源。
同樣也需要也注冊:
this.Resuming += App_Resuming; void App_Resuming(object sender, object e) { var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; if (localSettings.Values.ContainsKey("currentpage")) { MemoryData.CurrentPage = localSettings.Values["currentpage"].ToString(); } }
開啟
當應用程序被啟動時,會觸發OnLaunch事件,該事件包含PreviousExecutionState屬性,包含三個值:
Terminated、ClosedByUser、NotRunning、Running、Suspended
當值為Terminated時,必須還原已保存的會話數據,以使應用程序完全保持用戶上次看到的界面。若為ClosedByUser、NotRunning時,則可忽略之前的會話數據,按默認方式顯示。
protected override void OnLaunched(LaunchActivatedEventArgs args) { if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; if (localSettings.Values.ContainsKey("currentpage")) { MemoryData.CurrentPage=localSettings.Values["currentpage"].ToString(); } if (MemoryData.CurrentPage == "Page1") { Window.Current.Content = new Page1(); } } Frame frame = new Frame(); frame.Navigate(typeof(LoginPage)); Window.Current.Content = frame; CurrentDispatcher = Window.Current.Dispatcher; Window.Current.Activate(); }
大概的機制狀態就這些,我通過Logo跟蹤了一下程序執行的狀態,體會深刻一些,大家也不妨試一下~