成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

詳解Windows Phone開發(fā)中的墓碑機(jī)制

移動(dòng)開發(fā)
墓碑機(jī)制是系統(tǒng)自動(dòng)完成的,但是數(shù)據(jù)的保存和恢復(fù)則是我們通過代碼控制的。另外墓碑機(jī)制也不是萬(wàn)能的,因?yàn)榇藭r(shí)程序是終止的,如果有一些下載,播放,計(jì)時(shí)的功能就無法通過墓碑機(jī)制完成到了。

目前的智能手機(jī),硬件上已經(jīng)可以媲美幾年前的PC機(jī)了,1G內(nèi)存,512M以上內(nèi)存,3.5以上的屏幕,3G,WIFI等等都成為了新的手機(jī)的最低標(biāo)準(zhǔn)。而Windows Phone也一改以往WM手機(jī)硬件差異大的問題,設(shè)定了最低的硬件標(biāo)準(zhǔn)。相對(duì)于以前系統(tǒng),性能上,操作上,流暢度上也有了很大提高。但是電池的發(fā)展遠(yuǎn)遠(yuǎn)跟不上手機(jī)的耗電量。大的也就1500MA的電池,最多也就使用1天多,大部分每天都用充電。為了節(jié)約電量,各個(gè)平臺(tái)的手機(jī)都推出了一些省電的措施。

對(duì)于Windows Phone來說,剛推出時(shí)和iPhone第一版一樣,不支持多任務(wù),一方面是為了給前臺(tái)程序提供更多的資源,更流暢的體驗(yàn),另一方面也是為了介紹電池的消耗。同事采用了消息推送機(jī)制來完成一部分后臺(tái)操作,也使用了一種名為墓碑機(jī)制來對(duì)實(shí)現(xiàn)所謂的了“偽多任務(wù)”。 到了最新的“芒果”系統(tǒng),已經(jīng)支持了多任務(wù),但也不同于以往WM說或PC上的多任務(wù),也改進(jìn)了墓碑機(jī)制,加快了程序間的切換。我們這一篇文章就了解下Windows Phone平臺(tái)的偽多任務(wù)。

一、偽多任務(wù)

在我們使用PC和WM系統(tǒng)時(shí),多任務(wù)對(duì)我們來說是理所應(yīng)當(dāng)?shù)摹R贿吢牳瑁贿吷螿Q,還能上微博發(fā)照片。可到了Windows Phone上卻不支持多任務(wù)了,對(duì)于一個(gè)新的智能系統(tǒng)來說,確實(shí)無法讓人接受。但是多任務(wù)存在一個(gè)問題就是如果開的任務(wù)過多,系統(tǒng)用起來就會(huì)比較卡,在WM系統(tǒng)中這種情況比較常見。為了提供用戶的體驗(yàn),目前的一些智能系統(tǒng)都放棄了這種傳統(tǒng)的多任務(wù)方式,而采用了偽多任務(wù),有限制的多任務(wù)和消息推送這些方法。

所謂的偽多人他并不是真正的多任務(wù),只是通過一些處理,讓用戶使用起來感覺不到和多任務(wù)有什么區(qū)別。在Windows Phone中采用了墓碑機(jī)制來實(shí)現(xiàn)偽多任務(wù)。墓碑這個(gè)名字也很恰當(dāng)。當(dāng)我們運(yùn)行了一個(gè)程序后,切換到另一個(gè)程序,這時(shí)因?yàn)槭菃稳蝿?wù),第一個(gè)程序會(huì)被終止掉,但是采用墓碑機(jī)制,保存了程序當(dāng)前的狀態(tài)和數(shù)據(jù),當(dāng)我們?cè)谇袚Q回的時(shí)候,雖然是啟動(dòng)了一個(gè)新的實(shí)例,但是可以通過墓碑來恢復(fù)到之前的狀態(tài),所以用戶感覺不到有什么區(qū)別。

墓碑機(jī)制是系統(tǒng)自動(dòng)完成的,但是數(shù)據(jù)的保存和恢復(fù)則是我們通過代碼控制的。另外墓碑機(jī)制也不是萬(wàn)能的,因?yàn)榇藭r(shí)程序是終止的,如果有一些下載,播放,計(jì)時(shí)的功能就無法通過墓碑機(jī)制完成到了。Windows Phone 7則通過推送機(jī)制來解決部分問題,而WP7.1 SDK中也提供了一些后臺(tái)操作來解決這些問題,這一篇文章我們主要介紹墓碑機(jī)制。

二、程序執(zhí)行模型

在深入了解墓碑機(jī)制之前我們必須弄清楚程序的執(zhí)行模型。下面這個(gè)圖就是Windows Phone 7.1中最新的執(zhí)行模型。此圖來自于MSDN,但是他的圖有個(gè)錯(cuò)誤,修改了下。

程序執(zhí)行模型

對(duì)于一個(gè)Windows Phone程序來說,他有啟動(dòng)---運(yùn)行---休眠---墓碑---退出等5個(gè)狀態(tài),狀態(tài)切換之間存在一些事件和方法。下面就具體介紹一個(gè)程序從啟動(dòng)到終止的過程。

1.啟動(dòng)一個(gè)程序

我們啟動(dòng)一個(gè)程序有多種方法,最普遍的就是在第一屏界面點(diǎn)擊程序的Tile圖標(biāo)或者是在第二屏中點(diǎn)擊程序圖標(biāo),另外我們可以通過點(diǎn)擊一個(gè)推送的Toast消息或者通過Launchers 和 Choosers來啟動(dòng)程序,這些后面會(huì)介紹。在啟動(dòng)程序是,會(huì)觸發(fā)Application的Launching事件。這個(gè)事件我們前面提到過,他是PhoneApplicationService類中注冊(cè)的事件,除此之外好包含了三個(gè)和程序狀態(tài)相關(guān)的事件。

程序啟動(dòng)會(huì)會(huì)創(chuàng)建一個(gè)新的實(shí)例,為了保證程序能過正常快速的啟動(dòng),我們不應(yīng)該在Launching事件中執(zhí)行過多的代碼,比如讀取文件,網(wǎng)絡(luò)連接等等,這樣會(huì)印象用戶體驗(yàn),我們可用另起一個(gè)線程來執(zhí)行這些操作。

2.程序運(yùn)行

程序啟動(dòng)以后就進(jìn)入了運(yùn)行狀態(tài),程序從啟動(dòng)到進(jìn)入第一個(gè)頁(yè)面的過程我們?cè)谇懊嬗懻擁?yè)面導(dǎo)航的文章中詳細(xì)介紹過了。通過從配置文件獲得要加載的第一個(gè)XAML頁(yè)面,讀取XAML文件并生成新的實(shí)例,通過Frame顯示出這個(gè)Page。我們知道在進(jìn)入一個(gè)Page時(shí)會(huì)執(zhí)行OnNavigatedTo方法。當(dāng)這些完成后,程序才真正進(jìn)入了運(yùn)行狀態(tài)。而OnNavigatedTo方法對(duì)于墓碑機(jī)制來說非常重要,我們一般在這個(gè)方法中進(jìn)行一些數(shù)據(jù)恢復(fù)的操作。

3.休眠狀態(tài)

這個(gè)狀態(tài)是在WP7.1中新加入的一個(gè)狀態(tài),是為了提升多個(gè)任務(wù)間的切換速度。當(dāng)我們?cè)诔绦蛑悬c(diǎn)擊Win鍵進(jìn)入到主界面,或者是在程序中使用了Launchers 和Choosers啟動(dòng)了另一個(gè)程序時(shí)就會(huì)發(fā)生(不是所有都會(huì)發(fā)生)。休眠狀態(tài)時(shí),程序停止運(yùn)行,但是整個(gè)進(jìn)程還是存在于內(nèi)存中。當(dāng)恢復(fù)這個(gè)程序時(shí),就不需要?jiǎng)?chuàng)建一個(gè)新的實(shí)例。這樣就加快了程序恢復(fù)和切換的速度。而且從休眠狀態(tài)恢復(fù)時(shí)我們一不需要去恢復(fù)數(shù)據(jù)。而在WP7.1中,我們可以長(zhǎng)按Back按鈕,出現(xiàn)程序列表,然后選擇要前臺(tái)執(zhí)行的程序。

在切換到其他程序,進(jìn)入到休眠狀態(tài)之前,會(huì)調(diào)用當(dāng)前頁(yè)面的OnNavigatedFrom方法,在這個(gè)方法中我們可以保存當(dāng)前頁(yè)面的一些數(shù)據(jù)狀態(tài);然后會(huì)觸發(fā)Application中的Deactivated事件,在這個(gè)事件中,我們可以保存一些當(dāng)前程序的數(shù)據(jù)。我們知道,因?yàn)檫M(jìn)程資源還保存在內(nèi)存中,所以當(dāng)前臺(tái)程序使用時(shí),內(nèi)存不足或者不足以讓程序流暢運(yùn)行,這時(shí)系統(tǒng)就會(huì)執(zhí)行一些操作來釋放內(nèi)存,此時(shí)程序就可能從休眠狀態(tài)變換為下面介紹的墓碑狀態(tài)。

4.墓碑狀態(tài)

如上面說的,在WP7.1中,只有系統(tǒng)資源不夠前臺(tái)程序使用時(shí),后臺(tái)程序才可能從休眠狀態(tài)進(jìn)入到墓碑狀態(tài)。這也是WP7.1相對(duì)于WP7.0最大的改進(jìn)。在WP7.0中,系統(tǒng)沒有休眠狀態(tài),仍和后臺(tái)程序都是直接進(jìn)入到墓碑狀態(tài),而OnNavigatedFrom方法和Deactivated事件都是在進(jìn)入墓碑轉(zhuǎn)臺(tái)前觸發(fā)的。一個(gè)程序進(jìn)入到墓碑狀態(tài)時(shí),他的進(jìn)程被終止掉,但是程序的回退棧中的信息,以及我們保存的一些信息會(huì)保留在內(nèi)存中。

為了保證系統(tǒng)資源和性能,Windows Phone對(duì)墓碑狀態(tài)也做了一些限制。目前系統(tǒng)中之允許同時(shí)存在5個(gè)墓碑程序。當(dāng)超過了這個(gè)數(shù)量或者因?yàn)榍芭_(tái)程序需要更多的資源,那么系統(tǒng)就會(huì)完全終止掉我們的程序,包括閃存內(nèi)存中保存的回退棧和數(shù)據(jù)信息。所以對(duì)于我們而言,好需要對(duì)這種情況進(jìn)行處理。

5.程序恢復(fù)

當(dāng)我們使用Back按鈕或者長(zhǎng)按Back從任務(wù)列表中返回程序,或者是從Launchers 或Choosers返回時(shí),程序就會(huì)恢復(fù)執(zhí)行。但是如圖上看到的,我們程序可能是從休眠狀態(tài),也可能是從墓碑狀態(tài)返回的。如果是從休眠狀態(tài)返回時(shí)我們不需要做任何恢復(fù)的操作,而從墓碑程序中返回,我們就需要恢復(fù)程序的狀態(tài)和數(shù)據(jù),以便用戶感覺程序是被重寫創(chuàng)建了。

程序恢復(fù)時(shí)會(huì)觸發(fā)Application類中的Activated事件,我們可以通過檢查IsApplicationInstancePreserved參數(shù)來判斷程序是從休眠狀態(tài)還是墓碑狀態(tài)返回的,在此方法中我們可以用來恢復(fù)之前在Deactivated事件中保存的數(shù)據(jù)。如果是從休眠狀態(tài)恢復(fù),不會(huì)重新執(zhí)行構(gòu)造函數(shù),而從墓碑狀態(tài)恢復(fù)時(shí)會(huì)重新執(zhí)行構(gòu)造函數(shù)。因?yàn)锽ack Stack在墓碑狀態(tài)中還是保存在內(nèi)存中的,所以這是會(huì)返回到我們程序退出時(shí)所在的頁(yè)面,在進(jìn)入到頁(yè)面之前還是會(huì)執(zhí)行OnNavigatedTo方法,對(duì)于墓碑狀態(tài)恢復(fù)的程序,我們可以在這個(gè)方法中來恢當(dāng)前頁(yè)面的狀態(tài)數(shù)據(jù)。

6.程序結(jié)束

在Windows Phone的silverlight框架程序中,我們唯一退出程序的方法就是點(diǎn)擊Back鍵,當(dāng)Back Stack中不存在頁(yè)面時(shí)程序就會(huì)退出,目前系統(tǒng)沒有提供任何Exit方法來以代碼的方式結(jié)束程序。在程序退出時(shí)會(huì)觸發(fā)Application中最后一個(gè)事件,Closing。在這個(gè)事件中我們可以釋放一些使用的資源,保存數(shù)據(jù)等等,要注意的是,如果一個(gè)程序從墓碑狀態(tài)被結(jié)束,是不會(huì)觸發(fā)此事件的。MSDN上說關(guān)閉程序的時(shí)間被限制在10s,超過這個(gè)時(shí)間程序會(huì)被終止掉。

#p#

三、數(shù)據(jù)保存和恢復(fù)

至此,我們對(duì)于Windows Phone的執(zhí)行模型也有了一定了解,即便WP7.1中引入了休眠方式,但是程序還是可能進(jìn)入到墓碑模式或則被終止掉。所以無論什么情況,我們都要對(duì)數(shù)據(jù)進(jìn)行保存和恢復(fù)。不過我們可以通過一些系統(tǒng)狀態(tài)來判斷是否需要進(jìn)行數(shù)據(jù)保存和恢復(fù)。

在進(jìn)入到墓碑狀態(tài)時(shí),數(shù)據(jù)會(huì)被保存到內(nèi)存中,系統(tǒng)為我們提供了數(shù)據(jù)字典來保存我們的數(shù)據(jù)。 對(duì)于程序來說,系統(tǒng)的狀態(tài)和數(shù)據(jù)我們可以存放到Application.State這個(gè)字典這種,而對(duì)于單個(gè)頁(yè)面來說數(shù)據(jù)可以存放到Page.State的字典中。需要注意的是這些字典中存入的數(shù)據(jù)必須是可序列化的數(shù)據(jù)。另外我們也可以把數(shù)據(jù)保存到隔離存儲(chǔ)區(qū)中。

有了數(shù)據(jù)保存的區(qū)域下面就是數(shù)據(jù)保存的時(shí)機(jī),在Application相關(guān)的: Launching、Deactivated、Activated和Closing這4個(gè)事件中我們可以對(duì)系統(tǒng)的數(shù)據(jù)進(jìn)行保存和恢復(fù),而在每個(gè)頁(yè)面進(jìn)入和離開都會(huì)發(fā)生的OnNavigatedTo和OnNavigatedFrom,我們可以用來保存和恢復(fù)頁(yè)面的數(shù)據(jù)。

1.單頁(yè)面的情況

單頁(yè)面的情況 單頁(yè)面的情況

我們看個(gè)列子,Demo5中我們新建了2個(gè)頁(yè)面。在MianPage中有一個(gè)TextBox和三個(gè)按鈕。點(diǎn)擊Add時(shí),TextBox的值會(huì)增加(默認(rèn)是1),而點(diǎn)擊Next按鈕會(huì)導(dǎo)航到Page1頁(yè)面,點(diǎn)擊Run Camera按鈕會(huì)調(diào)用相機(jī)。代碼運(yùn)行環(huán)境是WP7.1 SDK Beta2。我們?cè)贏pplication的四個(gè)事件和頁(yè)面的2個(gè)方法中只加入運(yùn)行的Log信息。

  1. public MainPage()    
  2.  
  3. {    
  4.  
  5.    Debug.WriteLine("MainPage Constructor");    
  6.    camera = new CameraCaptureTask();    
  7.    camera.Completed += new EventHandler<PhotoResult>(camera_Completed);    
  8.    num = 1;    
  9.    InitializeComponent();    
  10.    txtNum.DataContext = num;    
  11.  
  12. }    
  13.  
  14. private void Button_Click(object sender, RoutedEventArgs e)    
  15.  
  16. {    
  17.  
  18.    txtNum.DataContext = ++num;    
  19.    Debug.WriteLine("Add Method,TextBox is {0}", num.ToString());    
  20.  

我們點(diǎn)擊Add讓TextBox值增加。然后點(diǎn)擊Win鍵回到住界面,然后點(diǎn)擊Back返回程序,并繼續(xù)點(diǎn)Add,程序Log信息如下:

  1. Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. Add Method,TextBox is 4    
  7. MainPage OnNavigatedFrom    
  8. Application_Deactivated    
  9. Application_Activated    
  10. MainPage OnNavigatedTo    
  11. Add Method,TextBox is 5    
  12. Add Method,TextBox is 6 

很明顯,因?yàn)樵赪P7.1下,程序進(jìn)入了休眠狀態(tài),所以我們TextBox不會(huì)被清空。讓我們?cè)谀M器上來模仿一下墓碑狀態(tài)的情況,需要進(jìn)行如下設(shè)置就可以了。

墓碑狀態(tài)

然后我們?cè)俅芜\(yùn)行程序,結(jié)果如下:

  1. Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. Add Method,TextBox is 4    
  7. MainPage OnNavigatedFrom    
  8. Application_Deactivated    
  9. The thread '<No Name>' (0xec600c2) has exited with code 0 (0x0).    
  10. The thread '<No Name>' (0xee100aa) has exited with code 0 (0x0).    
  11. The thread '<No Name>' (0xe6a00ae) has exited with code 0 (0x0).    
  12. 'UI Task' (Managed): Loaded 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\mscorlib.dll'    
  13. 'UI Task' (Managed): Loaded 'System.Windows.RuntimeHost.dll'    
  14. 'UI Task' (Managed): Loaded 'System.dll'    
  15. 'UI Task' (Managed): Loaded 'System.Windows.dll'    
  16. 'UI Task' (Managed): Loaded 'System.Net.dll'    
  17. 'UI Task' (Managed): Loaded 'System.Core.dll'    
  18. 'UI Task' (Managed): Loaded 'System.Xml.dll'    
  19. 'UI Task' (Managed): Loaded '\Applications\Install\F5BE083B-4EC0-4192-84B0-EE83323B8240\Install\Demo5.dll', Symbols loaded.    
  20. 'UI Task' (Managed): Loaded 'Microsoft.Phone.dll'    
  21. 'UI Task' (Managed): Loaded 'Microsoft.Phone.Interop.dll'    
  22. 'UI Task' (Managed): Loaded 'System.Runtime.Serialization.dll'    
  23. Application_Activated    
  24. MainPage Constructor    
  25. MainPage OnNavigatedTo    
  26. Add Method,TextBox is 2    
  27. Add Method,TextBox is 3 

 

很明顯看到,在執(zhí)行完Deactivated事件后程序的線程都結(jié)束了,而但我點(diǎn)擊Back按鈕后,重新加載了程序,并且執(zhí)行了MainPage的構(gòu)造函數(shù),而我們TextBox的值也從1開始了。下面看看如何來保存這些數(shù)據(jù)。對(duì)代碼修改如下:

  1. protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)    
  2.  
  3. {    
  4.  
  5.     Debug.WriteLine("MainPage OnNavigatedFrom");    
  6.     base.OnNavigatedFrom(e);    
  7.     State["num"] = num; //保存變量    
  8.  
  9. }   
  10.  
  11. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)    
  12.  
  13. {    
  14.  
  15.     Debug.WriteLine("MainPage OnNavigatedTo");    
  16.     base.OnNavigatedTo(e);    
  17.     num = (int)State["num"]; //恢復(fù)變量    
  18.  

 

我們?cè)贛ainPage的兩個(gè)方法中保存和恢復(fù)數(shù)據(jù),但是運(yùn)行卻出錯(cuò)了。因?yàn)镺nNavigatedTo中的State["num"]為空。因?yàn)槲覀兊谝淮芜M(jìn)入頁(yè)面時(shí)也會(huì)執(zhí)行這個(gè)方法,這時(shí)還沒有保存過num,所以就出錯(cuò)了。在WP7.0中我們可以使用 State.ContainsKey或者State.TryGetValue來避免這種錯(cuò)誤的發(fā)生,任何時(shí)候我們從字典中讀取數(shù)據(jù)時(shí)都必須檢查數(shù)據(jù)的有效性。而在WP7.1中我們有更好的辦法:

  1. protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)    
  2.  
  3. {    
  4.  
  5.     Debug.WriteLine("MainPage OnNavigatedFrom");    
  6.  
  7.     base.OnNavigatedFrom(e);    
  8.  
  9.     if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)    
  10.  
  11.     {    
  12.  
  13.         Debug.WriteLine("Save data");    
  14.  
  15.         State["num"] = num; //保存變量    
  16.  
  17.       }    
  18.  
  19. }   
  20.  
  21. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)    
  22.  
  23. {    
  24.  
  25.      Debug.WriteLine("MainPage OnNavigatedTo");    
  26.      base.OnNavigatedTo(e);    
  27.      if (e.NavigationMode != System.Windows.Navigation.NavigationMode.New)    
  28.      {    
  29.  
  30.          Debug.WriteLine("Recover data");    
  31.   object objNum;    
  32.   if (State.TryGetValue("num", out objNum))    
  33.   {    
  34.       num = (int)objNum;    
  35.   }   
  36.  
  37.      }    
  38.      txtNum.DataContext = num;    
  39.  

 

我們?cè)诳纯唇Y(jié)果:

  1. Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. Add Method,TextBox is 4    
  7. MainPage OnNavigatedFrom    
  8. Save data    
  9. Application_Deactivated    
  10. The thread '<No Name>' (0xfa800f2) has exited with code 0 (0x0).    
  11. The thread '<No Name>' (0xf9500e6) has exited with code 0 (0x0).    
  12. The thread '<No Name>' (0xe3700ee) has exited with code 0 (0x0).    
  13. 'UI Task' (Managed): Loaded 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\mscorlib.dll'    
  14. 'UI Task' (Managed): Loaded 'System.Windows.RuntimeHost.dll'    
  15. 'UI Task' (Managed): Loaded 'System.dll'    
  16. 'UI Task' (Managed): Loaded 'System.Windows.dll'    
  17. 'UI Task' (Managed): Loaded 'System.Net.dll'    
  18. 'UI Task' (Managed): Loaded 'System.Core.dll'    
  19. 'UI Task' (Managed): Loaded 'System.Xml.dll'    
  20. 'UI Task' (Managed): Loaded '\Applications\Install\F5BE083B-4EC0-4192-84B0-EE83323B8240\Install\Demo5.dll', Symbols loaded.    
  21. 'UI Task' (Managed): Loaded 'Microsoft.Phone.dll'    
  22. 'UI Task' (Managed): Loaded 'Microsoft.Phone.Interop.dll'    
  23. 'UI Task' (Managed): Loaded 'System.Runtime.Serialization.dll'    
  24. Application_Activated    
  25. MainPage Constructor    
  26. MainPage OnNavigatedTo    
  27. Recover data    
  28. Add Method,TextBox is 5    
  29. Add Method,TextBox is 6 

 

數(shù)據(jù)被正常恢復(fù)了,我們可以看到,OnNavigatedTo方法雖然被執(zhí)行了兩次,但是Recover data只有在從墓碑或休眠狀態(tài)返回時(shí)才執(zhí)行,而在新建時(shí)是沒有執(zhí)行的。因?yàn)樵赪P7.1中開放了NavigationEventArgs 的NavigationMode屬性。當(dāng)我們新建一個(gè)頁(yè)面進(jìn)入時(shí),此屬性為New,而當(dāng)我們從墓碑狀態(tài)或其他頁(yè)面返回時(shí)則是Back,很明顯我們只有在Back時(shí)才需要恢復(fù)數(shù)據(jù)。而在OnNavigatedFrom方法中,當(dāng)我們導(dǎo)航到新的頁(yè)面時(shí),此屬性為New,而當(dāng)我們回退到前一個(gè)頁(yè)面時(shí),此屬性為Back,我們知道Windows Phone中只有Back Stack,所以從一個(gè)頁(yè)面返回到前一個(gè)頁(yè)面時(shí),這個(gè)頁(yè)面就會(huì)被回收,所以就沒有必要保存數(shù)據(jù)了。而在WP7中我們每次都要進(jìn)行保存和恢復(fù)操作。

但是這里還有一個(gè)問題,就是當(dāng)我們從休眠狀態(tài)返回時(shí),是不需要進(jìn)行數(shù)據(jù)恢復(fù)的,但是此方法還是會(huì)被執(zhí)行,在WP7.1中同樣提供了方法,可以在休眠狀態(tài)返回時(shí)不執(zhí)行這些操作。我們?cè)贏pplication的Activated 事件中可以判斷,我們修App代碼如下:

  1. public static bool IsTombstoning { get; set; }    
  2. private void Application_Activated(object sender, ActivatedEventArgs e)    
  3.  
  4. {    
  5.  
  6.    Debug.WriteLine("Application_Activated");    
  7.    if (e.IsApplicationInstancePreserved)    
  8.    {    
  9.  
  10.        IsTombstoning = false;    
  11.  
  12.    }    
  13.    else    
  14.    {    
  15.  
  16.        IsTombstoning = true;    
  17.  
  18.    }    
  19.  

 

WP7.1中新增了IsApplicationInstancePreserved屬性來判斷是休眠狀態(tài)還是墓碑狀態(tài)恢復(fù)的。我們?cè)贏pp中定義了一個(gè)靜態(tài)的IsTombstoning屬性。在MainPage的OnNavigatedTo方法中使用就行了。有一點(diǎn)要注意的是不要在App的構(gòu)造函數(shù)中對(duì)IsTombstoning 賦值,否則從墓碑狀態(tài)返回后會(huì)執(zhí)行構(gòu)造函數(shù),另外也不要在頁(yè)面中定義一個(gè)變量來指示是否是新的實(shí)例,因?yàn)槟阈枰4婊蚧謴?fù)這個(gè)變量。取消Debug中的墓碑調(diào)試,我們看看結(jié)果。

  1. Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. Add Method,TextBox is 4    
  7. Add Method,TextBox is 5    
  8. Add Method,TextBox is 6    
  9. MainPage OnNavigatedFrom    
  10. Save data    
  11. Application_Deactivated    
  12. Application_Activated    
  13. MainPage OnNavigatedTo    
  14. Add Method,TextBox is 7 

 

2.多頁(yè)面的情況

前面已經(jīng)了解了單頁(yè)面情況下的數(shù)據(jù)恢復(fù),那么如果我們從主頁(yè)面切換到其他頁(yè)面,這時(shí)進(jìn)入了休眠或墓碑狀態(tài)又會(huì)怎么樣呢?因?yàn)檫@是我們當(dāng)前已經(jīng)不是在MainPage頁(yè)面了。還是在Demo5中,我們點(diǎn)擊Add后,點(diǎn)擊Next按鈕,進(jìn)入到Page1,然后點(diǎn)Win鍵,進(jìn)入主菜單。在Page1中我們沒有進(jìn)行數(shù)據(jù)存儲(chǔ)和恢復(fù),我們只關(guān)心MainPage中的數(shù)據(jù)。我們就看看墓碑情況,運(yùn)行結(jié)果如下:

  1. Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. Main Pgee Navigate to Page1    
  7. Page1 Constructor    
  8. MainPage OnNavigatedFrom    
  9. Save data    
  10. Page1 OnNavigatedTo    
  11. Page1 OnNavigatedFrom    
  12. Application_Deactivated    
  13. The thread '<No Name>' (0xf88012a) has exited with code 0 (0x0).    
  14. The thread '<No Name>' (0xe220156) has exited with code 0 (0x0).    
  15. The thread '<No Name>' (0xf1d014a) has exited with code 0 (0x0).    
  16. 'UI Task' (Managed): Loaded 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\mscorlib.dll'    
  17. 'UI Task' (Managed): Loaded 'System.Windows.RuntimeHost.dll'    
  18. 'UI Task' (Managed): Loaded 'System.dll'    
  19. 'UI Task' (Managed): Loaded 'System.Windows.dll'    
  20. 'UI Task' (Managed): Loaded 'System.Net.dll'    
  21. 'UI Task' (Managed): Loaded 'System.Core.dll'    
  22. 'UI Task' (Managed): Loaded 'System.Xml.dll'    
  23. 'UI Task' (Managed): Loaded '\Applications\Install\F5BE083B-4EC0-4192-84B0-EE83323B8240\Install\Demo5.dll', Symbols loaded.    
  24. 'UI Task' (Managed): Loaded 'Microsoft.Phone.dll'    
  25. 'UI Task' (Managed): Loaded 'Microsoft.Phone.Interop.dll'    
  26. 'UI Task' (Managed): Loaded 'System.Runtime.Serialization.dll'    
  27. Application_Activated    
  28. Page1 Constructor    
  29. Page1 OnNavigatedTo    
  30. Bace to MainPage    
  31. MainPage Constructor    
  32. Page1 OnNavigatedFrom    
  33. MainPage OnNavigatedTo    
  34. Recover data    
  35. Add Method,TextBox is 4 

 

事實(shí)證明,我們前面寫的代碼依舊有效,沒有進(jìn)行任何修改就完成了任務(wù)。我們看到在導(dǎo)航到Page1之前就進(jìn)行了數(shù)據(jù)保存。因?yàn)镺nNavigatedFrom不僅在進(jìn)入墓碑狀態(tài)前回執(zhí)行,在離開當(dāng)前頁(yè)面時(shí)也會(huì)執(zhí)行。所以,即便是在Page1中進(jìn)入了墓碑狀態(tài),當(dāng)我們返回程序,并返回到MainPage頁(yè)面是,還是會(huì)執(zhí)行OnNavigatedTo方法來恢復(fù)數(shù)據(jù),這時(shí)的頁(yè)面Mode也是Back。所以我們不需要為多頁(yè)面做特殊處理。

我們考慮下,如果從Page1頁(yè)面不是GoBack,而是使用Navigate方法重新導(dǎo)航到MainPage呢?這有什么關(guān)系,只不過是新建了一個(gè)頁(yè)面的實(shí)例,我們前一個(gè)MainPage還在Back Stack中。那么數(shù)據(jù)會(huì)恢復(fù)到這個(gè)MainPage中嗎,當(dāng)然不會(huì),我們使用的State屬性是每個(gè)頁(yè)面實(shí)例特有的。那我我如果想在每個(gè)新建的MainPage中都能繼續(xù)進(jìn)行Add操作呢?

對(duì)于這種變態(tài)的需求,一般我是懶得做,肯定是你設(shè)計(jì)有問題,但是這里還是演示下如何實(shí)現(xiàn)。除了使用Page的State,前面我們還提到使用Application的State,這個(gè)是所有頁(yè)面共享的。我們?cè)赑age中增加一個(gè)New按鈕,然后修改MainPage的方法:

  1. protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)    
  2.  
  3. {    
  4.  
  5.     Debug.WriteLine("MainPage OnNavigatedFrom");    
  6.     base.OnNavigatedFrom(e);    
  7.     Debug.WriteLine("Save data");    
  8.     PhoneApplicationService.Current.State["num"] = num; //保存到全局    
  9.  
  10. }    
  11.  
  12. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)    
  13.  
  14. {    
  15.  
  16.     Debug.WriteLine("MainPage OnNavigatedTo");    
  17.     base.OnNavigatedTo(e);    
  18.     Debug.WriteLine("Recover data");    
  19.     object objNum;    
  20.     if (PhoneApplicationService.Current.State.TryGetValue("num", out objNum))    
  21.     {    
  22.         num = (int)objNum;    
  23.  txtNum.DataContext = num;    
  24.     }    
  25.  

 

為了一個(gè)變量能在不同實(shí)例中同時(shí)起作用,并公用,我們修改了頁(yè)面的方法。這里保存和恢復(fù)數(shù)據(jù)時(shí)都不在判斷是否是New或Back,因?yàn)槿魏吻闆r我們都要保存和恢復(fù),以便在所有頁(yè)面中使用。另外我們可以使用隔離數(shù)據(jù)區(qū)來存儲(chǔ)和恢復(fù)。結(jié)果就是,無論我們?cè)赑age1頁(yè)面從墓碑返回后, New一個(gè)MainPage,還是Back,或者是先New然后在返回到前一個(gè)MainPage,結(jié)果都是在任何頁(yè)面都能對(duì)這個(gè)數(shù)據(jù)繼續(xù)的使用。

當(dāng)然更好的辦法是在App中定義一個(gè)全局的變量,這樣我們不需要在Page的頁(yè)面中對(duì)這些數(shù)據(jù)進(jìn)行保存和恢復(fù),只需要在Appliation的事件中進(jìn)行。這樣代碼會(huì)很簡(jiǎn)潔。

  1. public static int Number { get; set; }    
  2. private void Application_Activated(object sender, ActivatedEventArgs e)    
  3. {    
  4.  
  5.    Debug.WriteLine("Application_Activated");    
  6.    if (e.IsApplicationInstancePreserved)    
  7.    {    
  8.  
  9.        IsTombstoning = false;    
  10.  
  11.    }    
  12.    else    
  13.    {    
  14.  
  15.        IsTombstoning = true;    
  16.        Number = (int)PhoneApplicationService.Current.State["number"];    
  17.    }    
  18.  
  19. }    
  20.  
  21. private void Application_Deactivated(object sender, DeactivatedEventArgs e)    
  22.  
  23. {    
  24.  
  25.      Debug.WriteLine("Application_Deactivated");    
  26.      PhoneApplicationService.Current.State["number"] = Number;    
  27.  

 

App中代碼修改如上,我們?cè)贏ctivated和Deactivated中進(jìn)行數(shù)據(jù)恢復(fù)和保存,因?yàn)锳ctivated必定是在Deactivated執(zhí)行后執(zhí)行,所以這里沒有判斷是否存在。但還是應(yīng)該寫的嚴(yán)謹(jǐn)一些。下面是MainPage中的代碼:

  1. protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)    
  2. {    
  3.  
  4.     Debug.WriteLine("MainPage OnNavigatedFrom");    
  5.     base.OnNavigatedFrom(e);    
  6.     App.Number = num;    
  7.  
  8. }    
  9.  
  10. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)    
  11. {    
  12.  
  13.     Debug.WriteLine("MainPage OnNavigatedTo");    
  14.     base.OnNavigatedTo(e);    
  15.     num = App.Number;    
  16.     txtNum.DataContext = num;    
  17.  

 

代碼是非常的簡(jiǎn)單,如果不是為了掩飾保存和恢復(fù),我們甚至可以直接對(duì)App.Number來操作。相比前一種方法,代碼簡(jiǎn)潔了很多。結(jié)果這里就不貼了。

3.使用Chooser的情況

在程序中我們可以使用Launcher或者Chooser來運(yùn)行系統(tǒng)提供的API功能,比如打電話,發(fā)短信,調(diào)用相機(jī)等等。具體的使用我們后面會(huì)介紹。一般使用這些API都會(huì)導(dǎo)致當(dāng)期那程序變?yōu)楹笈_(tái)程序。所以也存在數(shù)據(jù)恢復(fù)的問題,但是對(duì)于Chooser來說,他會(huì)返回?cái)?shù)據(jù),而Lanucher不會(huì)返回?cái)?shù)據(jù),那么這個(gè)時(shí)候就存在一個(gè)新得到的數(shù)據(jù)和被保存的數(shù)據(jù)我們應(yīng)該用哪一個(gè)的問題。

看下面的列子,我們調(diào)用相機(jī),返回后得到圖片的大小,把大小填入TextBox。

  1. private CameraCaptureTask camera;   
  2.  
  3. public MainPage()    
  4. {    
  5.    num = 1;    
  6.    camera = new CameraCaptureTask();    
  7.    camera.Completed += new EventHandler<PhotoResult>(camera_Completed);    
  8.    InitializeComponent();    
  9.    txtNum.DataContext = num;    

 

我們先定義相機(jī)的Chooser,注意這里要定義成類變量,而不能是局部變量,并且設(shè)置完成事件的處理方法。因?yàn)槿绻蔷植孔兞浚?dāng)系統(tǒng)進(jìn)入到墓碑狀態(tài)在返回時(shí),這個(gè)對(duì)象就沒有了,就沒辦法執(zhí)行完成事件了,對(duì)于Chooser來說也沒有辦法獲得得到返回的數(shù)據(jù)了。

  1. private void Button_Click_2(object sender, RoutedEventArgs e)    
  2. {    
  3.  
  4.     Debug.WriteLine("Run Camera");    
  5.     try    
  6.     {    
  7.  
  8.        camera.Show();    
  9.  
  10.     }    
  11.     catch (System.InvalidOperationException ex)    
  12.     {    
  13.  
  14.        MessageBox.Show(ex.Message);    
  15.  
  16.     }    
  17. }    
  18.  
  19. void camera_Completed(object sender, PhotoResult e)    
  20. {    
  21.  
  22.     if (e.TaskResult == TaskResult.OK)    
  23.     {    
  24.  
  25.         BitmapImage bmp = new BitmapImage();    
  26.  bmp.SetSource(e.ChosenPhoto);    
  27.  num = bmp.PixelHeight;    
  28.  
  29.     }    
  30.     else    
  31.     {    
  32.  
  33.          num = 1024; //模擬器沒法拍照    
  34.  
  35.      }    

 

以上我們點(diǎn)擊Run Camera按鈕時(shí),就調(diào)用Show方法調(diào)出,拍完照片后吧照片的高度設(shè)置到TextBox,因?yàn)槟M器拍不了,就手動(dòng)設(shè)置到1024。頁(yè)面的數(shù)據(jù)我們采用第一種,單頁(yè)面的保存方式。

  1. Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. Run Camera    
  7. MainPage OnNavigatedFrom    
  8. Save data    
  9. Application_Deactivated    
  10. Application_Activated    
  11. Set carmera num    
  12. MainPage OnNavigatedTo    
  13. Add Method,TextBox is 1025 

 

從上面結(jié)果可見程序調(diào)用相機(jī)時(shí)進(jìn)入休眠狀態(tài) ,返回后先執(zhí)行了完成函數(shù),Set carmera num后數(shù)據(jù)變成了1024。因?yàn)槭切菝卟恍枰謴?fù)狀態(tài),所以在此加1后變?yōu)?025。我們?cè)诳纯磸哪贡疇顟B(tài)返回的結(jié)果。

  1. Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. Run Camera    
  7. MainPage OnNavigatedFrom    
  8. Save data    
  9. Application_Deactivated    
  10. The thread '<No Name>' (0xf3802a2) has exited with code 0 (0x0).    
  11. The thread '<No Name>' (0xe0a02da) has exited with code 0 (0x0).    
  12. The thread '<No Name>' (0xea002da) has exited with code 0 (0x0).    
  13. 'UI Task' (Managed): Loaded 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\mscorlib.dll'    
  14. 'UI Task' (Managed): Loaded 'System.Windows.RuntimeHost.dll'    
  15. 'UI Task' (Managed): Loaded 'System.dll'    
  16. 'UI Task' (Managed): Loaded 'System.Windows.dll'    
  17. 'UI Task' (Managed): Loaded 'System.Net.dll'    
  18. 'UI Task' (Managed): Loaded 'System.Core.dll'    
  19. 'UI Task' (Managed): Loaded 'System.Xml.dll'    
  20. 'UI Task' (Managed): Loaded '\Applications\Install\F5BE083B-4EC0-4192-84B0-EE83323B8240\Install\Demo5.dll', Symbols loaded.    
  21. 'UI Task' (Managed): Loaded 'Microsoft.Phone.dll'    
  22. 'UI Task' (Managed): Loaded 'Microsoft.Phone.Interop.dll'    
  23. 'UI Task' (Managed): Loaded 'System.Runtime.Serialization.dll'    
  24. Application_Activated    
  25. MainPage Constructor    
  26. Set carmera num    
  27. MainPage OnNavigatedTo    
  28. Recover data    
  29. Add Method,TextBox is 4 

 

我們發(fā)現(xiàn)從墓碑狀態(tài)返回后,雖然也進(jìn)行了Set carmera num,但是還進(jìn)行了Recover data,最新得到數(shù)據(jù)被之前恢復(fù)的數(shù)據(jù)覆蓋了。我們看到返回后先執(zhí)行了頁(yè)面的構(gòu)造函數(shù),然后執(zhí)行了相機(jī)的完成方法,這里要注意的是,不要在這里操作控件,因?yàn)榇藭r(shí)Load事件還沒有執(zhí)行,這里操作控件會(huì)拋出一個(gè)空引用異常。

獲得的數(shù)據(jù)和保存的數(shù)據(jù)間的選擇是比較容易碰到的問題。我們要根據(jù)自己的邏輯來選擇解決的方法,這里我們使用最新的數(shù)據(jù)來代替保存的數(shù)據(jù)。所以修改恢復(fù)數(shù)據(jù)的部分:

  1. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)    
  2. {    
  3.  
  4.    Debug.WriteLine("MainPage OnNavigatedTo");    
  5.    base.OnNavigatedTo(e);    
  6.    //單頁(yè)面情況    
  7.       if (App.IsTombstoning)    
  8.       {    
  9.  
  10.        if (e.NavigationMode != System.Windows.Navigation.NavigationMode.New)    
  11.        {    
  12.  
  13.           if (num == 1)    
  14.    {    
  15.  
  16.             Debug.WriteLine("Recover data");    
  17.      object objNum;    
  18.      if (State.TryGetValue("num", out objNum))    
  19.      {    
  20.  
  21.                num = (int)objNum;    
  22.  
  23.             }    
  24.  
  25.           }    
  26.  
  27.        }    
  28.  
  29.     }    
  30.  
  31.     txtNum.DataContext = num;    

 

我們知道如果進(jìn)入到墓碑狀態(tài)返回后,num的數(shù)據(jù)會(huì)丟失,而我們?cè)跇?gòu)造函數(shù)中把num設(shè)置為1。因?yàn)樵谡{(diào)用OnNavigatedTo之前會(huì)執(zhí)行方法相機(jī)的返回方法camera_Completed。如果num被設(shè)置為1024就不應(yīng)該恢復(fù)數(shù)據(jù)。所以我們可以在OnNavigatedTo中通過num的值來判斷是否恢復(fù),如果是1就需要恢復(fù),如果不是就說明有新的值。

這里需要注意,如果在 camera_Completed中得到的數(shù)據(jù)就是1,那么還是會(huì)被恢復(fù),所以一定根據(jù)情況來。這里只是舉例子。另外我們要注意構(gòu)造函數(shù)中num初始化和camera.Completed事件綁定之間的順序,一定要先初始化數(shù)據(jù),最后在注冊(cè)完成事件,否則執(zhí)行完camera_Completed方法后,num又被初始化了。

下面看看執(zhí)行結(jié)果:

  1. <strong>Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. Run Camera    
  7. MainPage OnNavigatedFrom    
  8. Save data    
  9. Application_Deactivated    
  10. The thread '<No Name>' (0xe83037a) has exited with code 0 (0x0).    
  11. The thread '<No Name>' (0xeb50372) has exited with code 0 (0x0).    
  12. The thread '<No Name>' (0xf53033a) has exited with code 0 (0x0).    
  13. 'UI Task' (Managed): Loaded 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\mscorlib.dll'    
  14. 'UI Task' (Managed): Loaded 'System.Windows.RuntimeHost.dll'    
  15. 'UI Task' (Managed): Loaded 'System.dll'    
  16. 'UI Task' (Managed): Loaded 'System.Windows.dll'    
  17. 'UI Task' (Managed): Loaded 'System.Net.dll'    
  18. 'UI Task' (Managed): Loaded 'System.Core.dll'    
  19. 'UI Task' (Managed): Loaded 'System.Xml.dll'    
  20. 'UI Task' (Managed): Loaded '\Applications\Install\F5BE083B-4EC0-4192-84B0-EE83323B8240\Install\Demo5.dll', Symbols loaded.    
  21. 'UI Task' (Managed): Loaded 'Microsoft.Phone.dll'    
  22. 'UI Task' (Managed): Loaded 'Microsoft.Phone.Interop.dll'    
  23. 'UI Task' (Managed): Loaded 'System.Runtime.Serialization.dll'    
  24. Application_Activated    
  25. MainPage Constructor    
  26. Set carmera num    
  27. MainPage OnNavigatedTo    
  28. Add Method,TextBox is 1025    
  29. </strong> 

 

和之前的區(qū)別就在于這里沒有恢復(fù)數(shù)據(jù),最后使用的是相機(jī)得到的數(shù)據(jù)。對(duì)于沒有調(diào)用相機(jī),而是點(diǎn)擊Win導(dǎo)致的程序恢復(fù),這時(shí)恢復(fù)的數(shù)據(jù),結(jié)果正確:

  1. Application_Launching    
  2. MainPage Constructor    
  3. MainPage OnNavigatedTo    
  4. Add Method,TextBox is 2    
  5. Add Method,TextBox is 3    
  6. MainPage OnNavigatedFrom    
  7. Save data    
  8. Application_Deactivated    
  9. The thread '<No Name>' (0xebe0382) has exited with code 0 (0x0).    
  10. The thread '<No Name>' (0xeb203be) has exited with code 0 (0x0).    
  11. The thread '<No Name>' (0xec103d6) has exited with code 0 (0x0).    
  12. 'UI Task' (Managed): Loaded 'C:\Program Files\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE\mscorlib.dll'    
  13. 'UI Task' (Managed): Loaded 'System.Windows.RuntimeHost.dll'    
  14. 'UI Task' (Managed): Loaded 'System.dll'    
  15. 'UI Task' (Managed): Loaded 'System.Windows.dll'    
  16. 'UI Task' (Managed): Loaded 'System.Net.dll'    
  17. 'UI Task' (Managed): Loaded 'System.Core.dll'    
  18. 'UI Task' (Managed): Loaded 'System.Xml.dll'    
  19. 'UI Task' (Managed): Loaded '\Applications\Install\F5BE083B-4EC0-4192-84B0-EE83323B8240\Install\Demo5.dll', Symbols loaded.    
  20. 'UI Task' (Managed): Loaded 'Microsoft.Phone.dll'    
  21. 'UI Task' (Managed): Loaded 'Microsoft.Phone.Interop.dll'    
  22. 'UI Task' (Managed): Loaded 'System.Runtime.Serialization.dll'    
  23. Application_Activated    
  24. MainPage Constructor    
  25. MainPage OnNavigatedTo    
  26. Recover data    
  27. Add Method,TextBox is 4 

 

#p#

四、禁用墓碑

如果你擁有一臺(tái)真機(jī),在升級(jí)到到芒果之前,或許總是要忍受恢復(fù)程序時(shí)的"Resuming"的提示。當(dāng)然也不是沒有辦法,網(wǎng)上就流傳了修改注冊(cè)表來禁用墓碑狀態(tài)的方法。首先你需要有一臺(tái)已經(jīng)越獄的機(jī)器,然后下載一個(gè)RegistryEditor的XPA軟件包。運(yùn)行這個(gè)軟件,把\HKLM\Software\Microsoft\TaskHost\DehydrateOnPause的鍵值從3修改為0。再試試,程序切換的很快了,"Resuming"基本也不出現(xiàn)了。我買手機(jī)的時(shí)候Mango的Beta版已經(jīng)出了,而且注冊(cè)表也已經(jīng)被賣家修改好了。所以在手機(jī)上還沒見到"Resuming"就升級(jí)到Mango了。在我升級(jí)到7712之后,偶爾卻會(huì)出現(xiàn)"Resuming",所以決定研究下修改這個(gè)注冊(cè)表的作用。

搜索了好久,終于找到了一篇相關(guān)的文章:Tombstoning, Dehydration, and Windows Phone 。從文章中我們可以了解到,這個(gè)鍵值有4個(gè)選項(xiàng):

1、Don’t dehydrate;

2、Forcefully dehydrate;

3、Gracefully dehydrate;

4、Automatically decide。

表示程序在暫停時(shí)是否執(zhí)行Dehydrate,Dehydrate愿意是脫水。在進(jìn)入墓碑狀態(tài)后,一些系統(tǒng)級(jí)別的操作會(huì)停止,運(yùn)行環(huán)境開始回收資源,其中就包括.NET運(yùn)行時(shí),回收完以后整個(gè)程序的運(yùn)行環(huán)境也被回收了。這樣一個(gè)過程就叫做Dehydrate。

系統(tǒng)默認(rèn)是3,表示命令程序的運(yùn)行環(huán)境在合適的時(shí)候優(yōu)雅的執(zhí)行Dehydrate。但是目前并不清楚是如何決定是否合適。但是對(duì)運(yùn)行環(huán)境來說默認(rèn)是執(zhí)行Dehydrate,但是也可以選擇不進(jìn)行Dehydrate。

HRESULT SHSetAutoDehydratingHostEligibility(BOOL fEligible); 

通過這個(gè)方法可以設(shè)置程序運(yùn)行環(huán)境是否進(jìn)行Dehydrate。當(dāng)我們選擇2時(shí),系統(tǒng)總是會(huì)執(zhí)行Dehydrate,而選擇1時(shí),系統(tǒng)會(huì)給程序發(fā)送一個(gè)WM_CLOSE消息來強(qiáng)制,理論上來說我們可以捕獲這個(gè)消息,來自己決定是否執(zhí)行Dehydrate。而當(dāng)設(shè)置為0是,Dehydrate被禁用了,也就是我們程序的運(yùn)行環(huán)境不會(huì)被回收,.NET運(yùn)行時(shí),程序的實(shí)例都不會(huì)被銷毀。而在我們恢復(fù)程序是,主要是創(chuàng)建新的實(shí)例和.NET運(yùn)行時(shí),導(dǎo)致了出現(xiàn)"Resuming"。

所以我們修改注冊(cè)表為0后,系統(tǒng)看起來就系象7.1中的休眠狀態(tài)一樣了。而且程序恢復(fù)也不會(huì)創(chuàng)建新的實(shí)例,所以并不清楚和WP7.1的休眠有什么區(qū)別。也有可能7.1的休眠也是采用這種方式,默認(rèn)不執(zhí)行Dehydrate,而在資源不足時(shí)執(zhí)行Dehydrate進(jìn)入墓碑。這樣在恢復(fù)時(shí)會(huì)有Resuming字樣,而在WP7.0中不執(zhí)行Dehydrate,當(dāng)資源不夠時(shí)程序會(huì)被結(jié)束,所以不會(huì)出現(xiàn)Resuming字樣。這是我個(gè)人的猜測(cè)。在Mango中用不了注冊(cè)表工具,沒法查看。也不知道此鍵值是否還效或者是否有修改。

另外系統(tǒng)規(guī)定只能有5個(gè)程序進(jìn)入墓碑狀態(tài),我在真機(jī)上看了下,最多也只能有5個(gè)第三方的程序運(yùn)行,而不管是休眠還是墓碑狀態(tài)。當(dāng)你開第六個(gè)程序時(shí),最早使用的程序就會(huì)被關(guān)閉,大家可以長(zhǎng)按Back按鈕來觀察。

五、總結(jié)

通過上面介紹我們發(fā)現(xiàn)對(duì)于我們程序而言,墓碑機(jī)制中對(duì)數(shù)據(jù)的保存和恢復(fù)是我們需要關(guān)注的地方。我們通過三種情況,介紹了對(duì)頁(yè)面已經(jīng)程序數(shù)據(jù)的保存和恢復(fù)方法,以及決定是否恢復(fù)數(shù)據(jù)的一般方法。了解了程序的執(zhí)行模型。其中Page中的OnNavigatedTo和OnNavigatedFrom是最重要的方法。另外所有保存的數(shù)據(jù)必須可以被序列化。

下面是微軟關(guān)于執(zhí)行模型的最佳時(shí)間方法:http://msdn.microsoft.com/zh-cn/library/ff817009.aspx

其中介紹了一些文章中沒有涉及的部分,比如當(dāng)程序從墓碑模式被終止的時(shí)候需要保存數(shù)據(jù)到隔離區(qū)。所以我們應(yīng)該在Deactivated事件中就進(jìn)行這樣的操作,因?yàn)槲覀儫o法預(yù)料程序可能進(jìn)入的狀態(tài)。另外有一點(diǎn)要指出,當(dāng)我們程序被切換至后臺(tái),進(jìn)入到休眠或墓碑狀態(tài)時(shí),此時(shí)我們點(diǎn)擊程序圖標(biāo),重新啟動(dòng)一個(gè)實(shí)例時(shí),之前的實(shí)例的數(shù)據(jù)都無法恢復(fù)。想解決這個(gè)問題只能把數(shù)據(jù)存放到隔離區(qū),然后恢復(fù)。但是會(huì)出現(xiàn)歡迎界面,對(duì)于有登陸界面的的還會(huì)出現(xiàn)登陸界面,我們需要進(jìn)行更多的處理,才能讓用戶感覺不到是新開的程序。另外其中還建議Application中的事件以及頁(yè)面中的兩個(gè)方法操作的時(shí)間不要超過10s,否則程序會(huì)被終止。但是我嘗試了下使用Thread.Sleep(15000),程序并沒有被終止。

責(zé)任編輯:王曉東 來源: cnblogs
相關(guān)推薦

2013-07-31 13:03:51

Windows PhoWindows Pho

2012-07-31 09:44:27

Windows Pho

2012-06-01 15:39:46

休眠狀態(tài)墓碑狀態(tài)

2012-02-02 16:37:51

Silverlight常用控件

2012-05-08 13:54:40

ToastPrompt

2014-12-22 14:21:57

Windows Pho隔離式存儲(chǔ)機(jī)制

2010-04-08 17:40:23

Windows Pho

2010-05-11 16:47:32

Windows Pho

2013-07-30 12:37:56

Windows PhoWindows Pho

2013-07-30 10:44:31

Windows PhoWindows Pho

2010-06-09 16:13:23

Windows Pho

2010-05-21 16:24:05

Windows Pho

2010-04-21 17:07:54

Windows Pho

2010-05-08 16:36:16

Windows Pho

2010-06-11 16:01:26

Windows Pho

2010-09-08 11:26:26

Windows PhoXNA 4.0 3D游戲開發(fā)

2013-04-17 14:00:06

Windows PhoWindows Pho

2011-06-07 12:42:15

Windows Pho

2013-04-16 17:02:50

Windows Pho概論

2013-04-19 16:34:56

Windows PhoWindows Pho
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 成年免费在线观看 | 亚洲精品一区二区三区蜜桃久 | 精品国产1区2区3区 一区二区手机在线 | 涩涩鲁亚洲精品一区二区 | 亚洲午夜精品一区二区三区他趣 | 一区二区三区四区五区在线视频 | 国产高清免费在线 | 7777在线视频 | 亚洲一区在线日韩在线深爱 | 欧美a在线 | 久久久久久国产 | 久久久.com| 国产成人精品一区二区三区在线 | 色橹橹欧美在线观看视频高清 | 极品国产视频 | 国产成人在线视频播放 | 久久aⅴ乱码一区二区三区 亚洲国产成人精品久久久国产成人一区 | 久久久久9999 | 在线播放91 | 亚洲一级黄色 | 成人三级网址 | 黄色一级大片在线免费看产 | 天天操天天干天天透 | 欧美综合一区二区 | 视频一区二区在线 | 91麻豆精品国产91久久久久久 | 久久久久久国产精品免费免费男同 | 欧美一级二级在线观看 | 断背山在线观看 | 亚洲网址在线观看 | 久久88 | 日韩欧美网 | 久久国产成人 | 天天操天天射综合网 | 日韩中文在线观看 | 黄色免费在线观看网址 | 久久久久久久国产精品影院 | av激情在线| 久久精品 | 91看片在线观看 | 久久久久久久久久久久久久久久久久久久 |