• <WP7>(七)手把手教你写天气预报程序:加入TombStone(墓碑机制)


    上一节完成后,程序已经能够正常运行了。基本功能都完成了。是不是有种很不出的感觉呢。大家都应该听说过会这个墓碑机制了吧。因为window phone 是单任务系统,为后台程序留了5个坑。程序一旦进入后台,就休眠了。被埋在坑里了,就不再运行了。只有你按返回键才能从进入休眠的后台程序。不过,我觉得还有两个问题,第一个就是如果程序在后台,你从启动器启动程序,就是不是按返回键进入程序,那么程序就重新运行了。原来后台的数据就没了,这个是一个用户体验很不好的地方,比如我,就是不喜欢按返回键进入程序的,喜欢从启动器进入后台程序。第二个,就是只有5个坑,一旦你的程序进入后台之后,又有5个程序进入后台,那么你程序埋在坑里的尸体就被抛尸荒野了。再也不能从后台进入了,只能从启动器重新打开。。

    那么,怎么解决呢,大家都是喜欢多任务运行的。我们就来模拟一把吧。

    模拟之前,先要了解程序的生命周期,这些大家还是百度吧。现在只是简单说下涉及到声明周期要使用到的函数。在App.xaml.cs里面定义了那么4个函数,Launching,Activate,Deactivate,Closing。Launching在程序启动的时候执行。Deactivate在用户点击开始键或者其他导致程序进入后台的操作时候执行,Activate在用户按返回键进入程序的时候执行。closing不用多说,看名字就知道。在程序关闭的时候执行。

    在我们这个程序,也就在设置页面的时候如果中断运行进入后台的话才需要恢复,所以相对简单些。我的方案是:定义了两个变量,一个是保存当前所在页面的CurrentPage(保存到PhoneApplicationService),一个是保存是否中断到后台的Recovery。.在Deactivate函数里面保存需要的相关值和上面两个变量到Isolatedstorage。并且在Launching的时候把原来Deactivate保存的值取出来。然后再PageLoad 的时候判断是否是中断恢复。是的话就导航到相关页面,然后恢复界面值。恢复完成,Recovery设置为false,并且保存到Isolatedstorage。

     

    在写代码之前,还要了解的是每个Page里面都有两个事件,OnNavigatedFrom和OnNavigatedTo,前者就是离开页面的时候执行,后者是进入页面的时候执行。重载这两个事件就能用了。

     

    下面先修改App.xaml.cs的代码:(代码中可能没添加命名空间,自己加吧,很简单)

    IsolatedStorageSettings iss = IsolatedStorageSettings.ApplicationSettings;
            private void Application_Launching(object sender, LaunchingEventArgs e)
            {
    
                //如果数据库不存在则创建一个数据库,并且存入相关数据
    
                CreatDB();
    
                #region 把Deactivate保存的相关数据取出来
                string temp;
                if (iss.TryGetValue("LastPage", out temp))
                {
                    PhoneApplicationService.Current.State["CurrentPage"] = temp;
                }
                int index;
                if (iss.TryGetValue("cityIndex", out index))
                {
                    PhoneApplicationService.Current.State["cityIndex"] = index;
                }
                if (iss.TryGetValue("provIndex", out index))
                {
                    PhoneApplicationService.Current.State["provIndex"] = index;
                } 
                #endregion
            }
    
    
            private void Application_Deactivated(object sender, DeactivatedEventArgs e)
            {
                #region 程序即将进入后台,保存中断情况的相关数据
                iss["Recovery"] = true;
                if (PhoneApplicationService.Current.State.ContainsKey("cityIndex"))
                {
                    iss["cityIndex"] = PhoneApplicationService.Current.State["cityIndex"];
                }
                if (PhoneApplicationService.Current.State.ContainsKey("provIndex"))
                {
                    iss["provIndex"] = PhoneApplicationService.Current.State["provIndex"];
                }
                if (PhoneApplicationService.Current.State.ContainsKey("CurrentPage"))
                {
                    iss["LastPage"] = PhoneApplicationService.Current.State["CurrentPage"];
                } 
                #endregion
    
            }
    
            private void Application_Closing(object sender, ClosingEventArgs e)
            {
                //退出,
                iss["Recovery"] = false;
            }


    下面修改MainPage的代码:(PageLoad修改如下)

     

    private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
            {
                #region 判断是否是中断进入
                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("MainPage.xaml") && temp.Length > 0)
                            {
                                NavigationService.Navigate(new Uri("/WeatherForecast;component/" + temp, UriKind.Relative));
                            }
                            else
                            {
                                iss["Recovery"] = false;
                            }
                        }
                    }
                    else
                        PhoneApplicationService.Current.State["CurrentPage"] = "MainPage.xaml";
                }
                else
                    PhoneApplicationService.Current.State["CurrentPage"] = "MainPage.xaml";
                #endregion
                UpdateWeather();
            }


     

    我们主要做的是SetPage的中断进入后台的处理,所以,要重载OnNavigatedFrom事件来保存两个Listpicker的SelectedIndex。而且,要在PageLoad的时候判断是否是中断返回,如果是那么就恢复。不是就常规绑定。下面是修改或者增加的代码:

    private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
            {
                #region 判定是否是中断退出后进入,是就恢复数据
                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("SetPage.xaml"))
                            {
                                int provIndex = 0;
                                int cityIndex = 0;
                                if (PhoneApplicationService.Current.State.ContainsKey("provIndex"))
                                {
                                    provIndex = Convert.ToInt32(PhoneApplicationService.Current.State["provIndex"]);
                                }
                                if (PhoneApplicationService.Current.State.ContainsKey("cityIndex"))
                                {
                                    cityIndex = Convert.ToInt32(PhoneApplicationService.Current.State["cityIndex"]);
                                }
                                RecovListPickerItems(provIndex, cityIndex);//恢复数据
                                iss["Recovery"] = false;//设置为已经恢复
    
                            }
                            else
                                ProvLpDataBind();
                        }
                        else
                            ProvLpDataBind();
                    }
                    else
                        ProvLpDataBind();
                }
                else
                    ProvLpDataBind();
                #endregion
                PhoneApplicationService.Current.State["CurrentPage"] = "SetPage.xaml";
            }
    
            /// <summary>
            /// 恢复数据的时候绑定city的ItemSource,并且绑定两个ListPicker的当前选项
            /// </summary>
            /// <param name="provIndex"></param>
            /// <param name="cityIndex"></param>
            void RecovListPickerItems(int provIndex, int cityIndex)
            {
                provincelp.ItemsSource = prov;
                if (provIndex < 0 || provIndex >= prov.Length)
                {
                    provIndex = 0;
                }
                provincelp.SelectedIndex = provIndex;
                List<String> l = cityDataBind(prov[provIndex]);
                if (cityIndex < 0 || cityIndex >= l.Count())
                {
                    cityIndex = 0;
                }
                citylp.SelectedIndex = cityIndex;
    
            }
    
            /// <summary>
            /// 离开页面保存当前两个ListPicker的selectedIndex
            /// </summary>
            /// <param name="e"></param>
            protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
            {
                base.OnNavigatedFrom(e);
                PhoneApplicationService.Current.State["provIndex"] = provincelp.SelectedIndex;
                PhoneApplicationService.Current.State["cityIndex"] = citylp.SelectedIndex;
            }
    这样,多任务模拟就完成了。无论是从返回键返回程序还是从启动器启动返回程序。都行。不过,如果要做的页面太多,控件太多还真是很麻烦的。

     

    PS:这里的断点调试技巧:由于要测试从启动器恢复程序,但是编译器调试的时候,一旦点击开始按钮进入后台,然后从启动器进入程序,编译器调试就退出了。因为原来的程序已经终结了。其实我们可以这样。点击开始按钮进入后台后,回到编译器点击终止调试,然后再次启动启动。那么这样的话就可以到需要调试的断点了。毕竟这里的判断还是很多,容易出错。其实这个是利用的是Isolatedstorage的特点,模拟器不关闭这个Isolatedstorage的数据是不会丢失的。

     

    这节工程下载:chapter7

     

    继续学习:<WP7>(八)手把手教你写天气预报程序:自定义about消息框和程序收尾

  • 相关阅读:
    Android 压力测试工具Monkey
    解决maven的依赖总是无法下载完成
    JDBC连接数据库(二)
    JDBC连接数据库(一)
    webdriver js点击无法点击的元素
    多线程Java面试题总结
    PHP unset销毁变量并释放内存
    ThinkPHP函数详解:D方法
    PHP 函数:intval()
    ThinkPHP 模板显示display和assign的用法
  • 原文地址:https://www.cnblogs.com/fengyun1989/p/2476980.html
Copyright © 2020-2023  润新知