Windows Phone 7 學習筆記 - 生命周期/墓碑化
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 {}21:47:49 TOMBSTONE:OnNavigatedTo at {}21:47:49 TOMBSTONE:OnNavigatedFrom at {}21:48:45 “UI Task”(托管): 已加載“System.Runtime.Serialization.dll” TOMBSTONE:Application_Deactivated at {}21:48:46 TOMBSTONE:Application_Activated at {}21:49:01 TOMBSTONE:OnNavigatedTo at {}21:49:01 TOMBSTONE:OnNavigatedFrom at {}21:49:18 TOMBSTONE:Application_Closing at {}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& amp;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
本文來自zhangkai2237的博客,原文地址:http://www.cnblogs.com/zhangkai2237/archive/2012/02/18/2357661.html