Windows Phone 7 - 儲存目前Application狀態的主要方法
過去使用Windows Mobile的用戶一定會習慣開啟多個程式的時候,即使忽然從最後一個程式回
到第一個程式運作時,第一個程式裡的資料與狀態也會一直保持在離開前的樣子,這是因為過
去的做法是支援Multi-Thread的方式,當初的訴求是希望讓用戶在操作Windows Mobile也能像在
操作Windows一樣,可以開啟多個程式且任意的切換。(例如:透過HTC內鍵的Task Manager可協
助管理多個程式。)
然而這樣方便的操作方式,在Windows支援桌機程式或是高規格的Windows Embedded是基本功能,
但到了Mobile即便現在支援高規格的機型愈來愈多,但Mobile螢幕只有一個,用戶要一次操作多個
程式的情況不外乎:聽音樂時又想做其他的事(例如:看PDF、瀏覽網路等)。這樣的情況說明了,
其實用戶同一時間只會操作一個主要的程式。在iPhone所設計的iOS系統中,不難去發現也有這種設
計味道存在。當然這只是其中一個原因,另外一個原因,就是GC(Garbage Collection)與記憶體管理
的問題,在開發.NET程式時,其實很少會去注意到何時要做GC或做記憶體管理,因為.NET Framework
會自動去幫忙處理這些事情,但這樣方便的結果可能造成開發人員在開發時的失誤(因為老師沒有教?),
並且Framework針對GC的處理是需要額外的記憶體去做管理;二個情形的結果,也就造成了WM被拖慢
的問題。
Windows Phone 7開始一切就不一樣了,同一時間只會有一個程式運作著(當作不包括內鍵的音樂程式),
舉例來說:今天寫了一個可以從程式呼叫SMS application幫我寄發SMS的客製程式,當我從主程式跑
到SMS application時,其實主程式是被terminated。雖然主程式被終止了,但它的狀態與內容其實是被變
成了tombstoned。當再一次回到主程式時(與第一次啟動的程式已經是不同的instance了),tombstoned裡的
資訊會被重新載入,回到剛才你離開的畫面,但用戶輸入或從程式取出來的當時資料,卻都不存在了。
那麼,你也許會想知道tombostoned裡到底是幹什麼的?
‧tombostoned(或稱tombostoning)
它是一個過程,主要把應用程式目前的執行狀態、畫面狀態(例如:ScrollViewer的位置)加以儲存起來。
它發生於當用戶正在執行main application(如客製的程式)時,把程式焦點轉往其他程式(或稱呼叫其他程式)
時,WP7在終結該main application前會先把上述提到的資料儲存起來。(更詳細的說明可參考:
Execution Model Overview for Windows Phone)。
如上述的說明,我想大家就可以了解了,WP7將主程式暫存的資料裡,並不會包括:用戶輸入的資料或
是自己程式裡取出的結果。如果想要保持這些資料,並且在回到主程式時也能正常的顯示要該怎麼做呢?
根據Execution Model Overview for Windows Phone所提供的方法,主要分成二個重要的儲存媒介:
‧Persistent Data
該類型的資料主要儲存於Isolated Storage中,讓所有實例化該Applicatoin的instance共用的資料類型,如同:
Isolated Storage中的Application Setting。
‧Transient Data
該類別的資料主要儲存於PhoneApplicationService類別所提供的State dictiontry<key,value>中。應用程式被執行
時,WP7會將應用程式instance出來的變成一個實體,而這些實體都會獨立擁有一個PhoneApplicationService。
而tombostoned暫存的資料就是被儲存於此。因此,如果你想要暫存使用者輸入的資料或顯示的資料內容,
都可以將資料記錄在該資料類型中,等到程式被reactived時再一併取回來。
要特別注意的是:dictiontry<string, object>中的object是要能支搜serializable的才能正常儲存。
那麼要怎麼操作Transient Data呢?WP7主要提供二個方式:
在Execution Model Best Practices for Windows Phone中建議我們透過二個主要的方法來存取PhoneApplicationService
中的State Dictionary<key,value>屬性:
‧OnNavigatedFro
該方法作用於當instace變成tombostoned application時(例如:當主程式呼叫其他外部程式時或是用戶按下Start鍵時),
透過在State Dictionary中建立獨立的key來儲存相對應的value。
‧NavigatedTo
該方法作用於當用戶按下back鍵或呼叫的程式回到主程式時,tombostoned application會擷取儲存於State Dictionary中
的資料,將畫面還原到該離開時的狀態。此時,開發人員需要去override該方法,處理還原畫面時應該顯示的當時資
料內容。
使用範例:
1. 假設開發畫面中有一個TextBox需要輸入用戶的UserName。
2. 於該MainPage.xaml.cs中加上override:onNavigatedFrom與onNavigatedTo二個重要的事件:
1: protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
2: {
3: base.OnNavigatedFrom(e);
4: //檢查State的Dictionary中是否有存在UserName這個Key,有則先刪除,再將值填入。
5: if (PhoneApplicationService.Current.State.ContainsKey("UserName"))
6: {
7: PhoneApplicationService.Current.State.Remove("UserName");
8: }
9: PhoneApplicationService.Current.State.Add("UserName", txtUserName.Text);
10: }
11:
12: protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
13: {
14: base.OnNavigatedTo(e);
15: //取值前先檢查是否存在。如果存在則顯示。
16: if (PhoneApplicationService.Current.State.ContainsKey("UserName"))
17: {
18: string tValue = PhoneApplicationService.Current.State["UserName"].ToString();
19: txtUserName.Text = tValue;
20: }
21: }
3. 進行測試的方法:
(a)先啟動Debug進入該Application;
(b)進入程式時,在UserName的TextBox中輸入:pou。
(c)著按下Start鍵,此時你會發現Debug模式被結束了,畫面回到Start畫面;
(d)再按下Back鍵,此時畫面變成黑色的(10 seconds to reload,大約會停10秒。),
此時快按下Debug鍵,這時就可以看到Debug模式 進入OnNavigatedTo的事件裡把資
料顯示出來了。如下圖:
以上的範例主要說明如何實作把需要在程式被重新啟動時,需要客製顯示自己需要的內容專用的。
例如,如果今天顯示的資料是來自遠端的資料庫或WCF取得的,你不希望程式重新啟動時,又要重
頭連線再取得資料的過程,那就非常適合把需要的資料暫時寫入State Dictionary之中。
以上是針對Application如何暫存目前執行資料的部分。但也許你跟我在閱讀時會有一點疑問,
那tombstoned的資料,究竟會存多久呢?目前可以回答的是:
當用戶從Back鍵回到該程式時,WP7會new instance該應用程式,此時該tombstoned的資料就被會倒回去新的
instace之中,而該tombstoned的資料就消失了。
那麼如果今天Back鍵不是回到該程式時(例如:從A程式到B程式,然後按了Start鍵,又選了C程式),針對A程
式的tombstoned的資料會存在多少呢?還目前我還沒有找到相關的資訊,如果有知道的內容,我會繼續來補充。
另外,感謝老狗建議我先閱讀Execution Model內容,我才有辦法多了解並整理該篇內容。
[補充]
‧PhoneApplicationService
該類別主要由Microsoft.Phone.Shell來包含。它的任務在於控制該Application的任何一種狀態下的壽命,包括:
管理應程式該於閒置(idle)階段時該處理的任務、管理應用程式的狀態改變時需要觸發的事件等,該類別是在
tombstoneing過程中最重要的角色。
‧Page State
它是應用程式的visual state,任務在於協助OnNavigatedFrom與OnNavigatedTo時管理畫面狀態的資源。它儲存
的狀態資料包括:TextBox的內容、ScrollViewr的Scroll Position等用戶操作所遺留於畫面中的資料內容。
‧Application Lifecycle
下圖是介紹整個WP7每一個Application運作的生命週期。有助於了解Application在那些情形下,
會變成tombstoned;還有Execution Model的改變順序。
References:
‧Exercise 1: Introducing the Windows Phone Application Life Cycle—Tombstoning
‧Execution Model for Windows Phone (必讀)
‧PhoneApplicationService Class
‧Execution Model Best Practices for Windows Phone