Windows Phone 应用程序有以下几种状态: - Launching
- Closing
- Activated
- Deactivated
使用者按返回键将Closing应用程序,而按开始键后应用程序便会进入 Deactivated 的事件然后进入tombstoning(墓碑状态),而在 Deactivated 事件之后,使用者这时候可能会执行其他的应用程序或进行其他的操作,之后可能会按下返回键回到应用程序的执行,这个时候就会进入 Activated 事件, Activated 事件处理完毕之后,便会回到执行中的状态;那在这两个事件中,要处理甚么呢?您可以在这个事件中去储存一些暂时性的数据,而这些数据同时又是属于整个应用程序会使用到的,就可以在这些事件中去处理。 // Code to execute when the application is launching (eg, from Start) // This code will not execute when the application is reactivated private void Application_Launching(object sender, LaunchingEventArgs e) { MessageBox.Show("Launching"); } // Code to execute when the application is activated (brought to foreground) // This code will not execute when the application is first launched private void Application_Activated(object sender, ActivatedEventArgs e) { MessageBox.Show("Activated"); } // Code to execute when the application is deactivated (sent to background) // This code will not execute when the application is closing private void Application_Deactivated(object sender, DeactivatedEventArgs e) { MessageBox.Show("Deactivated"); } // Code to execute when the application is closing (eg, user hit Back) // This code will not execute when the application is deactivated private void Application_Closing(object sender, ClosingEventArgs e) { MessageBox.Show("Closing"); } 2. 页面导航
- Loaded 每一次页面的载入完成时,都会引发 Loaded 事件
- Unloaded 当从这个页面要巡览到另外一个页面时,就会引发 Unload 事件
- OnNavigatedFrom 当利用 NavigationService ,要从页面离开时会引发 OnNavigatedForm 事件,使用时必须要覆写 Page 事件
- OnNavigatedTo 当利用 NavigationService ,寻览到新的页面时,会引发新页面的 OnNavigatedTo 事件,使用时必须要覆写 Page 事件
在页面之间传递数据:
- 利用全局变量,在App.cs声明 public static string ShareString;
- 利用Url传值,类似Web
private void btnAdd_Click(object sender, RoutedEventArgs e) { NavigationService.Navigate(new Uri("/Page2.xaml?msg=2", UriKind.Relative)); }
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedTo(e); textBox1.Text = NavigationContext.QueryString["msg"]; }
- 利用 PhoneApplicationSerivce 中的 State 属性
PhoneApplicationService.Current.State["msg"] = "2";获取时:
object temp = null;
if (PhoneApplicationService.Current.State.TryGetValue("msg", out data)) textBox1.Text = (string)data;
-
利用 Isolated storage
private void btnUseStorage_Click(object sender, RoutedEventArgs e) { IsolatedStorageFile isofile = IsolatedStorageFile.GetUserStoreForApplication(); if (isofile.FileExists("/data.txt")) isofile.DeleteFile("/data.txt"); StreamWriter sw = new StreamWriter(isofile.CreateFile("/data.txt"), System.Text.Encoding.UTF8); sw.WriteLine("Some data from isolated storage"); sw.Close(); sw.Dispose(); isofile.Dispose(); NavigationService.Navigate(new Uri("/Page_UseStorage.xaml", UriKind.Relative)); }读取:
//資料讀取完畢時,更新UI使用的委派事件 delegate void deReadCompleted(string value); private void ReadStorageFile() { Thread.Sleep(11500); IsolatedStorageFile isofile = IsolatedStorageFile.GetUserStoreForApplication(); if (isofile.FileExists("/data.txt")) { StreamReader sr = new StreamReader(isofile.OpenFile("/data.txt", FileMode.Open), System.Text.Encoding.UTF8); string tmpString = sr.ReadLine(); sr.Close(); sr.Dispose(); this.Dispatcher.BeginInvoke(new deReadCompleted(ReadCompleted), new object[] { tmpString }); } else { this.Dispatcher.BeginInvoke(new deReadCompleted(ReadCompleted), new object[] { "file not found.." }); } isofile.Dispose(); }3.
Idle detection,闲置侦测 最后我们来看 Idle detection 的部分;什么是 Idle detection 呢?这功能就是在设定系统闲置相关的侦测;例如说,如果装置一段时间没有使用(操作)的话,那么首先系统会将屏幕变暗,以节省电源,而再经过一段时间之后,便会锁定装置,将屏幕整个关闭,而这时候就会进入了上面生命周期提到的 Deactivated 事件,之后应用程序也进入 tombstoning 的状态。那么当应用程序是用于拨放音乐,当装置锁定的情形下,我们仍然希望应用程序可以继续运作;或者应用程序是利用装置上的 sensor ( 例如 accelerometer ) 来进行,在应用程序执行过程中,可能长时间都不会有使用触控屏幕的情形,但这时候不希望系统进入待机的状态,那么这时候就要设定 Idle detection 了。 好,了解该注意的事项之后,首先来看看侦测闲置的模式;在 Windows Phone 7 中,Idle detection 有两种
- ApplicationIdleDetectinMode
- UserIdleDetectionMode
我们先来看 ApplicationIdleDetection 的部分;ApplicationIdleDetection 是应用程序闲置状态侦测,例如经过一段时间没有使用的话,装置会进入锁定,并且引发应用程序的 Deactivated 事件,随后应用程序进入 tombstoning 状态;ApplicationIdleDetectionMode 便是设定装置进入锁定时,应用程序会不会进入 tombstoning 状态,如果设定为关闭,那么将不会引发应用程序的 Deacticated 事件,也不会将应用程序进入 tombstoning ;好处是甚么呢?大约有下列几点 - 应用程序仍然在执行中
- 当用户返回应用程序时,由于没有进入 tombstoning 的状态,能够快速回复
而要注意的地方约略如下
- 应用程序仍然在执行,所以会继续的消耗电池的电力;请特别注意,装置同样会进入锁定状态,只是应用程序不会停止
- 所有有关 UI 的更新动作应该要停止,以节省电力的消耗
- 所有动画、Timer 等动作应该要停止
- Sensor 将会停止回报(例如 accelerometer 将会停止回报目前的数值)
- 在改变闲置侦测模式时,永远要先询问使用者是否同意
那么问题来了,要怎么去知道目前 ApplicationIdleDetectionMode 的状态,以及怎么知道目前装置是不是要被锁定了,进而做相关的处理动作呢?
这里我们借用一下 MSDN 网站上的图片来做说明
最外层的部分是 PhoneApplicationFrame ,装载了整个应用程序,包含 Page、Page 中显示的内容、 System tray(page 最上方显示时间、讯号状态的状态栏)、 Application bar 等;在一个应用程序中只会有一个 frame ,也是整个应用程序最上层的容器;frame 会回报目前页面的方向、目前可用(可供应用程序使用)的空间有多少等等,以便让各种应用程序有相同的行为与特性,而 Obscured、UnObscured 事件,这两个事件便是发生在 PhoneApplicationFrmae 中,接下来我们来看一下程序代码的部分 using Microsoft.Phone.Shell; Pprivate void SetAppIdleDetectionDisable() { //关闭侦测 PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled; PhoneApplicationFrame root = (App.Current.RootVisual) as PhoneApplicationFrame; if (root != null) { root.Obscured += new EventHandler<ObscuredEventArgs>(root_Obscured); root.Unobscured += new EventHandler(root_Unobscured); } else MessageBox.Show("Error"); }
在程序代码中可以看到,在把闲置状态侦测关闭之后,接着就是取得 PhoneApplicationFrame ,而 PhoneApplicationFrame 时也是透过 App 类别来取得,取得之后由于在相关的事件必须要有对应的处理动作,因此必须要挂载相关的事件;其中 Obscured 事件便是当进入锁定时会引发的事件,在这个事件中,可以去做将 Storyboard、UI 的更新动作停止的相关动作,例如下面这边以一个 Timer 为例子,在这个事件中会进行关闭的动作
void root_Obscured(object sender, ObscuredEventArgs e) { Debug.WriteLine("Unobscured"); if (e.IsLocked) { //當應用程式被Lock screen覆蓋時要處理的動作,停止動畫(storyboard)、UI更新等動作 timer.Stop(); } }
这样子就可以达到在装置进入锁定时,能够把一些不需要用到的部分关闭,以节省电力的使用。看完了关闭之后,那如果要重新把闲置状态侦测给开启呢? 设定回 Enable 就可以了?这个动作没有错,但是目前的 Windows Phone 7 版本尚未支持 ,目前闲置模式关闭之后,要重新启动唯一的方式就是整个应用程序必须要重新开启才行,这部分要特别留意。而 MSDN 中有提到,建议还是可以在应用程序中加入相关的程序代码,但同时要做错误处理,例如说 private void SetAppIdleDetectionEnable() { if (PhoneApplicationService.Current.ApplicationIdleDetectionMode != IdleDetectionMode.Enabled) { try { PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Enabled; } catch (InvalidOperationException ex) { //platform not souported MessageBox.Show("Can't enable application idledection"); } } }
这样在未来的更新中,系统支持上来之后,你的应用程序功能就可以立刻的正常运作了。
接下来来看 UserIdleDetectionMode 的部分,这个部分是侦测使用者闲置的状态,使用的方式跟刚刚 ApplicationIdleDetection 是极其类似的,主要的差异性笔者大致列一下
- 以目前来说,使用者闲置是指『当用户没有触碰屏幕操作,或是点选硬件按键时』,Sensor 的部分目前即使有改变(例如说转向等等),也是视为闲置中,这个部分在未来的更新中可能会有变更
- 当设定为 Disable 时,装置永远不会进入锁定
- UserIdleDetectionMode 是支持 Disable 以及 Enable 的
在关闭的时候,程序代码的部分大致会像下面这样 private void SetUserIdleDetectionDisable() { PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled; }
跟先前操作 ApplicationIdleDetection 的部分几乎是相同的,而重新启动的部分也是相当的类似 private void SetUserIdleDetectionEnable() { if (PhoneApplicationService.Current.UserIdleDetectionMode != IdleDetectionMode.Enabled) { try { PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Enabled; } catch (Exception ex) { //platform not souported MessageBox.Show("Can't enable user idledection"); } } }
这样便可以达到停止闲置状态的侦测,这对于一些单纯利用 Sensor 来进行操作的应用程序是相当有用的。
今天的介绍就到这边了,希望大家对于应用程序的生命周期以及相关的应用有初步的了解,赶紧动手来试试看吧!