一、概述
应用程序的生命周期详解可以参照Windows8.1开发中msdn文档http://msdn.microsoft.com/library/windows/apps/hh464925.aspx
应用程序生命周期中有三个状态:Running(运行中),Suspended(挂起,暂停),NotRunning(终止)。如图所示
那么Suspended与NotRuning有什么不同呢?Suspended意味着当用户切换到另一个程序,你的应用程序很可能将被暂停一段时间,直到用户切换回您的应用程序。在此期间,应用程序处于休眠状态,换句话说,在你的应用程序中的代码不运行,但应用程序的对象和变量,包括框架和状态的BackStack保存在内存中。这允许用户快速并流体的应用程序之间切换。但是,手机的操作系统有可能将选择终止您的应用程序,这意味着系统将从内存中删除与应用程序的对象和变量。这意味着,下次用户启动应用程序,它不会有任何记忆的应用程序的状态,而是创建新的实例。
什么情况下Phone会暂停应用程序,然后终止程序呢?多数发生在当系统需要应用程序占用的内存时。但如果手机耗尽电池或用户重新启动手机它也可能发生。您的应用程序被暂停或者挂起时,它可能在没有告知的情况下就终止了,进入NotRuning状态,所以我们需要在程序被暂停或者挂起,即Suspended之前,要迅速保存程序当前的状态(包括变量,对象等)。因此,我们需要运用技巧保存状态,下面是3种技巧。
二、掌握SuspensionManager
这项保存状态工作的大部分将完成在App class。 App class是App.xaml.cs.里面的。你将要重写在App class中要处理您的应用程序的方法。最重要的是重写应用程序每次启动都会调用的OnLaunched()方法和在程序暂停的前一瞬间调用的OnSuspending()方法。(下面的代码因为需要Basic 模板中的一些类,需要添加Basic 模板)
1、在App.xaml.cs里,找到OnLaunched()方法,在之间添加SuspensionManager的方法。
protected async override void OnLaunched(LaunchActivatedEventArgs e) { #if DEBUG if (System.Diagnostics.Debugger.IsAttached) { this.DebugSettings.EnableFrameRateCounter = true; } #endif Frame rootFrame = Window.Current.Content as Frame; // 不要在窗口已包含内容时重复应用程序初始化, // 只需确保窗口处于活动状态 if (rootFrame == null) { // 创建要充当导航上下文的框架,并导航到第一页 rootFrame = new Frame(); SuspensionManager.RegisterFrame(rootFrame, "appFrame");//注册,SuspensionManager.RegisterFrame告诉SuspensionManager哪个对象(rootFrame,在我们的应用程序的唯一的框架)将被暂停 // TODO: 将此值更改为适合您的应用程序的缓存大小 rootFrame.CacheSize = 1; if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) { // TODO: 从之前挂起的应用程序加载状态 await SuspensionManager.RestoreAsync(); } // 将框架放在当前窗口中 Window.Current.Content = rootFrame; } if (rootFrame.Content == null) { // 删除用于启动的旋转门导航。 if (rootFrame.ContentTransitions != null) { this.transitions = new TransitionCollection(); foreach (var c in rootFrame.ContentTransitions) { this.transitions.Add(c); } } rootFrame.ContentTransitions = null; rootFrame.Navigated += this.RootFrame_FirstNavigated; // 当导航堆栈尚未还原时,导航到第一页, // 并通过将所需信息作为导航参数传入来配置 // 新页面 if (!rootFrame.Navigate(typeof(Page1), e.Arguments)) { throw new Exception("Failed to create initial page"); } } // 确保当前窗口处于活动状态 Window.Current.Activate(); }
2、在在App.xaml.cs里,找到OnSuspending()方法,在之间添加SuspensionManager的方法
private async void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); // TODO: 保存应用程序状态并停止任何后台活动 await SuspensionManager.SaveAsync();//储存状态,应用被挂起时保存frame的当前状态。 deferral.Complete(); }
---------------------------------------------------------------------------------------下面的两种方法是利用数据储存方法来保存状态。
二、掌握Windows.Storage.ApplicationData.Current.LocalSettings
LocalSettings是一个简单的字典,它被保存到应用程序分配的存储区域。还有被称为Windows.Storage.ApplicationData.Current.RoamingSettings,它将数据保存到和所有的设备同步的文件夹类似的存储区域。现在,下面使用LocalSettings。(LocalSetting使用很简单)
1、在valueTextBox_TextChanged事件处理方法,添加以下代码:
private void valueTextBox_TextChanged(object sender, TextChangedEventArgs e) { Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;//创建LocalSetting localSettings.Values["value"] = valueTextBox.Text; }
2、在NavigationHelper_LoadState()方法中,添加
private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) { Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;//创建LocalSetting
if (localSettings.Values.ContainsKey("value")) { valueTextBox.Text = localSettings.Values["value"].ToString(); } }
三、掌握NavigationHelper
类似LocalSetting,NavigationHelper类运用也同样简单。
1、在NavigationHelper_SaveState()添加
private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e) { e.PageState["testvalue"] = valueText.Text; }
2、在NavigationHelper_LoadState()添加
private void NavigationHelper_LoadState(object sender, LoadStateEventArgs e) { if (e.PageState!=null&&e.PageState.ContainsKey("testvalue")) { valueText.Text=e.PageState["testvalue"].ToString(); } }
四、Resumming事件
Resumming事件在APP.xaml.cs中,当挂起后,再点进程序时发生。
如:
this.Resuming += OnResuming; ....... void OnResuming(object sender, object e) { TimeSpan elapsedTime = DateTimeOffset.Now - this.suspensionTime; double elapsedMilliseconds = elapsedTime.TotalMilliseconds; decimal elapsedDecimalSeconds = (decimal)Math.Round(elapsedMilliseconds / 1000.0, 1); Data.Value += elapsedDecimalSeconds; }
以上内容大部分来自Bob的教学视频,如有不对请指出。