本文是“Windows Phone 7 開發 31 日談”系列的第14日。
昨天,我們討論了使用位置資料為使用者提供一種更加熟悉的感覺。今天,我寫的內容可能是Windows Phone 7上面最有爭議的話題:多任務。
現在有大量的文章都在寫Windows Phone 7將會很糾結,在列表中第一位的就是“缺少多任務”。
Windows Phone 7確實有多任務
是的,這是我說的。這麼說因為這是真的。一個Windows Phone絕對是一個多任務的裝置。我可以在聽音樂的同時玩遊戲,或者在上網的時候收郵件。錯誤的訊息是我們應用程式的開發人員傳出的,在開發我們發現不能構建在後台啟動並執行程式。
在我為Windows Phone 7工作的幾個月中,我只能提出2個真正令人信服的在我的電話中運行後台應用程式的原因。
- 播放音樂的程式。如Pandora程式。我完全認同它在後台中運行。如果音樂停止了使用者一定會發現的。
- 需要從裝置感應器中擷取資料的程式,如GPS,如果程式沒有運行,我就無法告訴你已經走完了你想走的4英裡路程。
在這兩種情況之外,我並沒有覺得有哪些情況是必須要讓程式能在後台啟動並執行。(如果你的程式在上述任何一類中,你可以向“當權者”呼籲要訪問一個能使程式在後台啟動並執行“超級API”。但我還是要提醒你……為擷取訪問權準備一個非常充分的理由。)
你可能會問“但是我如何從我的Web Service中獲得更新呢?難道我不用運行就能擷取嗎?”我的答案是NO,你不能這麼做。有一個叫做推播通知服務的強大機制可以以一種優雅的方式解決這個問題,這個我會在第19日中講解。
對於剩下的程式,有一個叫做“墓碑”的機制允許我們讓程式看起來總是在運行,即使進程已經被結束。示範了它是如何工作的:
正如你在中看到的,當使用者進入或退出程式時我們可以利用停用和重新啟用事件。通過這些事件,我們可以讓使用者覺得程式從來沒有停止過運行。當我們加入隔離儲存區 (Isolated Storage)(第15日)和推播通知(第19日)時,這將會變為一個非常給力的故事。
類比多任務
在你的App.xaml.cs檔案中有四個內建的方法(想瞭解專案檔結構的更多資訊,請參見第1日)。來看一下帶有內建注釋的預設狀態。
代碼 // 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方法用於非常規方式的進入和退出。例如,使用返回鍵回到我們的應用程式。或者由於接電話而離開程式。這些都是非常規的。我建議大量測試這些情況,但有一些規則可以遵循。
你應該在使用者退出程式時使用這些方法來儲存狀態資訊,並且在他們返回時更新這些狀態,這樣就產生了他們從未退出的錯覺。這麼做的原因很簡單:
- 大多數使用者都不會意識到在他們離開程式後,程式仍然在後台消耗著系統資源和電池電量(如果你正在閱讀本文,就你不屬於大多數使用者了)。
- 大多數應用程式都沒有在後台啟動並執行必要。這是節省系統資源的好方法。
在程式被停用時儲存你的狀態
在使用者退出時要做的第一件事就是儲存它們的資訊。在我的例子中,我構建了一個看似一直在啟動並執行計時器,即使當它沒有運行時。如果你想看全部代碼,翻到文章底部,見“下載程式碼範例”一節。我只在這裡展示和墓碑相關的部分代碼,但文章底部的代碼是完整可用的應用程式。
為了儲存資料,我使用PhoneApplicationService類。我會在明天(第15日)講解隔離儲存區 (Isolated Storage),一種更持久的儲存資料的方法。在我的例子中,我想知道你何時退出了程式,所以我要計算你退出時和下次運行程式時兩者之間的差值。
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
PhoneApplicationService.Current.State["LeftTime"] = DateTime.Now;
}
在我的應用程式中,當載入頁面時還有一個OnNavigatedTo事件。如果“LiftTime”的值存在,我就使用它,否則我假設你是第一次啟動程式。
在程式被重新啟用時恢複你的狀態
在這個例子中,我恢複了在退出時儲存下來的值。
代碼 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;
}
通過這種方法,我能保持一個連續的計時器,甚至是當我們離開程式時。如果你去問任何使用者,他們都會告訴你程式一直在運行。他們唯一能看到的現象是在程式載入較慢時出現的“Resuming”螢幕。實際上我不得不強製程序暫停才捕獲到下面的:
以上是墓碑機制背後的基礎知識。在退出時儲存狀態,並在回去時恢複。你的使用者絕不會知道這其中的差別,同時你還可以為他們提供更好的續航時間,效能和使用者體驗。
下載程式碼範例
相對於上面所述代碼的一個較複雜的例子,我的計時器一直在運行(即使在後台)。按下模擬器的開始按鍵退出,用返回鍵回到程式中。程式中還有一個文字框供你鍵入資訊,它會在你退出時被儲存。
原文地址:http://www.jeffblankenburg.com/post/31-Days-of-Windows-Phone-7c-Day-14-Tombstoning-%28Multi-tasking%29.aspx
如果大家喜歡我的文章,請點擊“推薦”,謝謝!