31天學會Windows Phone 7開發(fā):墓碑機制(多任務)
本文是《Windows Phone 7開發(fā)31日談》系列的第十四篇文章。上一篇,我們討論了使用位置數據為用戶提供一種更加熟悉的感覺。本文的內容可能是Windows Phone 7上面最有爭議的話題:多任務。
現在有大量的文章都在寫Windows Phone 7將會很糾結,在列表中第一位的就是“缺少多任務”。
Windows Phone 7確實有多任務
是的,這是我說的。這么說因為這是真的。一個Windows Phone絕對是一個多任務的設備。我可以在聽音樂的同時玩游戲,或者在上網的時候收郵件。錯誤的消息是我們應用程序的開發(fā)人員傳出的,在開發(fā)我們發(fā)現不能構建在后臺運行的程序。
在我為Windows Phone 7工作的幾個月中,我只能提出2個真正有說服力的在我的電話中運行后臺應用程序的原因。
◆播放音樂的程序。如Pandora程序。我完全認同它在后臺中運行。如果音樂停止了用戶一定會發(fā)現的。
◆需要從設備傳感器中獲取數據的程序,如GPS,如果程序沒有運行,我就無法告訴你已經走完了你想走的4英里路程。
在這兩種情況之外,我并沒有覺得有哪些情況是必須要讓程序能在后臺運行的。(如果你的程序在上述任何一類中,你可以向“當權者”呼吁要訪問一個能使程序在后臺運行的“超級API”。但我還是要提醒你……為獲取訪問權準備一個非常充分的理由。)
你可能會問“但是我如何從我的Web Service中獲得更新呢?難道我不用運行就能獲取嗎?”我的答案是NO,你不能這么做。有一個叫做推送通知服務的強大機制可以以一種優(yōu)雅的方式解決這個問題,這個我會在第19篇中講解。
對于剩下的程序,有一個叫做“墓碑”的機制允許我們讓程序看起來總是在運行,即使進程已經被結束。下圖演示了它是如何工作的:
正如你在上圖中看到的,當用戶進入或退出程序時我們可以利用停用和重新激活事件。通過這些事件,我們可以讓用戶覺得程序從來沒有停止過運行。當我們加入獨立存儲(第15篇)和推送通知(第19篇)時,這將會變?yōu)橐粋€非常給力的故事。
模擬多任務
在你的App.xaml.cs文件中有四個內建的方法(想了解項目文件結構的更多信息,請參見第1篇)。來看一下帶有內置注釋的默認狀態(tài)。
- // Code to execute when the application is launching (eg, from Start)
- // This code will not execute when the application is reactivated
- private void Application_Launching(object sender, LaunchingEventArgs e)
- {
- }
- // Code to execute when the application is activated (brought to foreground)
- // This code will not execute when the application is first launched
- private void Application_Activated(object sender, ActivatedEventArgs e)
- {
- }
- // Code to execute when the application is deactivated (sent to background)
- // This code will not execute when the application is closing
- private void Application_Deactivated(object sender, DeactivatedEventArgs e)
- {
- }
- // Code to execute when the application is closing (eg, user hit Back)
- // This code will not execute when the application is deactivated
- private void Application_Closing(object sender, ClosingEventArgs e)
- {
- }
“Launching”和“Closing”方法在通常情況下使用:通過通常方法啟動和退出應用程序(例如用返回鍵退出,或者從程序列表中啟動)。Activated和Deactivated方法用于非常規(guī)方式的進入和退出。例如,使用返回鍵回到我們的應用程序?;蛘哂捎诮与娫挾x開程序。這些都是非常規(guī)的。我建議大量測試這些情況,但有一些規(guī)則可以遵循。
你應該在用戶退出程序時使用這些方法來保存狀態(tài)信息,并且在他們返回時更新這些狀態(tài),這樣就產生了他們從未退出的錯覺。這么做的原因很簡單:
◆大多數用戶都不會意識到在他們離開程序后,程序仍然在后臺消耗著系統(tǒng)資源和電池電量(如果你正在閱讀本文,就你不屬于大多數用戶了)。
◆大多數應用程序都沒有在后臺運行的必要。這是節(jié)省系統(tǒng)資源的好方法。
在程序被停用時保存你的狀態(tài)
在用戶退出時要做的第一件事就是保存它們的信息。在我的例子中,我構建了一個看似一直在運行的計時器,即使當它沒有運行時。如果你想看全部代碼,翻到文章底部,見“下載代碼示例”一節(jié)。我只在這里展示和墓碑相關的部分代碼,但文章底部的代碼是完整可用的應用程序。
為了保存數據,我使用PhoneApplicationService類。我會在第15篇中講解獨立存儲,一種更持久的保存數據的方法。在我的例子中,我想知道你何時退出了程序,所以我要計算你退出時和下次運行程序時兩者之間的差值。
- private void Application_Deactivated(object sender, DeactivatedEventArgs e)
- {
- PhoneApplicationService.Current.State["LeftTime"] = DateTime.Now;
- }
在我的應用程序中,當載入頁面時還有一個OnNavigatedTo事件。如果“LiftTime”的值存在,我就使用它,否則我假設你是第一次啟動程序。
在程序被重新激活時恢復你的狀態(tài)
在這個例子中,我恢復了在退出時保存下來的值。
- protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
- if (PhoneApplicationService.Current.State.ContainsKey("LeftTime"))
- {
- DateTime deactivated = (DateTime)PhoneApplicationService.Current.State["LeftTime"];
- secondsSinceStart = (int)(DateTime.Now - deactivated).TotalSeconds + (int)PhoneApplicationService.Current.State["ElapsedTime"];
- writeTime();
- writeDate();
- timer.Start();
- }
- else secondsSinceStart = 0;
- }
通過這種方法,我能保持一個連續(xù)的計時器,甚至是當我們離開程序時。如果你去問任何用戶,他們都會告訴你程序一直在運行。他們唯一能看到的現象是在程序加載較慢時出現的“Resuming”屏幕。實際上我不得不強制程序暫停才捕獲到下面的截圖:
以上是墓碑機制背后的基礎知識。在退出時保存狀態(tài),并在回去時恢復。你的用戶絕不會知道這其中的差別,同時你還可以為他們提供更好的續(xù)航時間,性能和用戶體驗。
下載代碼示例
相對于上面所述代碼的一個較復雜的例子,我的計時器一直在運行(即使在后臺)。按下模擬器的開始按鍵退出,用返回鍵回到程序中。程序中還有一個文本框供你鍵入信息,它會在你退出時被保存。
原作者:Jeff Blankenburg 譯者:金山崟霸
中文來源:http://www.cnblogs.com/porscheyin/archive/2010/12/23/1914479.html
英文來源:http://www.jeffblankenburg.com/2010/10/14/31-days-of-windows-phone-day-14-tombstoning-multi-tasking/
【編輯推薦】