WP7是不支援多任務的,但是提供了一個TombStone機制,這個機制,通俗來說,就是提供了5個墳墓給你,如果你要你的程式進入“背景”,那麼就給你埋在那裡,如果你要啟用你的“背景”程式,就從墳墓裡把程式挖出來,并且從記憶體中把相關資料加載到控件,簡單來說就是借屍還魂。
但是,如果你的“背景”程式多于5個,那麼先進入墳墓裡面躺着的那個就不好意思了。要把你挖出來扔掉,讓新來的進去躺着。這樣的話,你想借屍還魂連屍體都找不到了。而且屍體消失的那一刻,記憶體中的魂也煙消雲散了。
這個機制涉及到的是應用程式的生命周期問題。這個問題網上一搜一大堆。就沒啥好讨論的。簡單來說,一開始程式運作,啟動的是Launch。然後如果點選開始鍵,那麼程式就進入Deactivate,程式進入“背景”,如果再次點選傳回鍵,程式就能從“背景”恢複。就是Activate。再次多次點選傳回鍵傳回到桌面。程式就退出了。就是Closing。這些東西在App.xaml都有定義。
還有一個關鍵的是,從“背景”傳回程式隻能按傳回鍵,如果是從啟動器上啟動程式,那麼前面的程式的線程就退出了。就是你重新打開了一個新的程式,這點我很不爽。如果我的程式是在第五個,那麼隻有2種方法從“背景”啟動程式,一種是長按傳回鍵,然後自己選擇進入背景程式,另一種是一種狂按傳回鍵,把前面四個“背景”程式退出了就傳回到第五個程式了。
是以,讓我很不爽的就是這兩點,一是隻有5個“背景程式”,二是不能從啟動器進入背景。
那麼,隻有自己模拟實作了。在Deactivate的時候,把資料都存在IsolatedStorage裡面。
下面實作的是擁有兩個頁面的程式,模拟在第二個頁面進入“背景”,是以僅僅恢複第二個頁面的資料。
首先添加一個叫Page2.xaml的頁面。并且在上面放上一個TextBox,Name為Page2Msg,
然後在MainPage.xaml放上一個Button,用來導航到Page2.xaml,添加click事件:
private void Button_Click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/TombStoneDemo;component/Page2.xaml",UriKind.Relative));
}
接下來就是重點了。我把目前所在頁面儲存到PhoneApplicationService。并且把Page2上的TextBox的内容也儲存到PhoneApplicationService。定義了一個IsolatedStorageSettings,key為“Recovery",布爾值,用來儲存是否要恢複中斷資料。
具體實作如下:
在MainPage的Loaded事件中實作:
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings;
bool recov;
if (iss.TryGetValue("Recovery", out recov))
{
if (recov)//是否恢複,恢複就導向Page2
{
if (PhoneApplicationService.Current.State.ContainsKey("CurrentPage"))
{
string temp = Convert.ToString(PhoneApplicationService.Current.State["CurrentPage"]);
if (!temp.Equals("MainPage.xaml") && temp.Length > 0)
{
NavigationService.Navigate(new Uri("/TombStoneDemo;component/" + temp, UriKind.Relative));//導航到CurrentPage。也就是以前的中斷頁面
}
}
}
else
PhoneApplicationService.Current.State["CurrentPage"] = "MainPage.xaml";
}
else
PhoneApplicationService.Current.State["CurrentPage"] = "MainPage.xaml";
}
在Page2中添加代碼:
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Page2 Loaded");
IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings;
bool recov;
if (iss.TryGetValue("Recovery", out recov))
{
if (recov)
{
if (PhoneApplicationService.Current.State.ContainsKey("CurrentPage"))
{
string temp = Convert.ToString(PhoneApplicationService.Current.State["CurrentPage"]);
if (temp.Equals("Page2.xaml"))
{
if (PhoneApplicationService.Current.State.ContainsKey("Page2txMsg"))
{
txMsg.Text = (string)PhoneApplicationService.Current.State["Page2txMsg"];
iss["Recovery"] = false;//恢複後設定這個屬性為false,就是恢複了
}
}
}
}
}
PhoneApplicationService.Current.State["CurrentPage"] = "Page2.xaml";
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
//離開Page2的時候儲存TextBox的值
PhoneApplicationService.Current.State["Page2txMsg"] = txMsg.Text;
}
了解TombStone的都知道,這個 PhoneApplicationService隻是儲存在記憶體中,如果從啟動器啟動程式,原來的記憶體裡面的内容也會被銷毀。是以,我要在中斷程式的時候把這些資料都儲存到IsolatedStorage。
在App.xaml裡面的Launching,Deactivate,CLosing添加代碼:
IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings;
private void Application_Launching(object sender, LaunchingEventArgs e)
{ //程式啟動的時候從存儲裡面讀取資料
string temp;
if (iss.TryGetValue("LastPage", out temp))
{
PhoneApplicationService.Current.State["CurrentPage"] = temp;
}
if (iss.TryGetValue("Page2txMsg", out temp))
{
PhoneApplicationService.Current.State["Page2txMsg"] = temp;
}
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{//程式中斷的時候儲存資料到IsolatedStorage。
iss["LastPage"] = PhoneApplicationService.Current.State["CurrentPage"];
iss["Recovery"] = true;
iss["Page2txMsg"] = PhoneApplicationService.Current.State["Page2txMsg"];
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
iss["Recovery"] = false;
}
這樣,就可以了。現在在Page2輸入任何資料到TextBox裡面。然後點選開始鍵。現在無論從傳回鍵進入程式,還是從啟動器啟動程式,都會傳回到我們剛才未編輯完的Page2界面。這樣,就模拟了多任務運作。
總結:現在是可以模拟了多任務運作。問題就是如果控件太多。頁面太多,那麼寫起來相當繁瑣。