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)); }
具体实现如下:
在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"; }
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;
}
在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; }
总结:现在是可以模拟了多任务运行。问题就是如果控件太多。页面太多,那么写起来相当繁琐。