WP7 - 儲存目前Application狀態的主要方法

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。

image

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的事件裡把資

料顯示出來了。如下圖:

image

 

以上的範例主要說明如何實作把需要在程式被重新啟動時,需要客製顯示自己需要的內容專用的。

例如,如果今天顯示的資料是來自遠端的資料庫或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的改變順序。

IC418879[1]

 

 

References:

Exercise 1: Introducing the Windows Phone Application Life Cycle—Tombstoning

Execution Model for Windows Phone (必讀)

Understanding the Windows Phone Application Execution Model, Tombstoning, Launcher and more… – Part 1

Understanding the Windows Phone Application Execution Model, Tombstoning, Launcher and more… – Part 2

Understanding the Windows Phone Application Execution Model, Tombstoning, Launcher and more… – Part 3.

PhoneApplicationService Class

Page.OnNavigatingFrom Method

Execution Model Best Practices for Windows Phone