WP7的生命周期一般说的是整个应用程序的声明周期,而不注重页面的生命周期,这跟Android是不一样的。WP7的生命周期基本如下图所示
应用程序基本分为四个状态,启动,关闭,激活和挂起。App类提供了4个事件,以便于程序处于不同状态时,开发人员可以对其做一些相应的处理。
1、Launching事件,第一次启动时触发,用户可以做一些初始化工作,比如加载一些数据
2、Closing事件,程序关闭时触发,用户可以做一些保存工作,以便用户下次打开层序时做一些还原
3、Activated事件、但程序被挂起之后,再次被激活时触发,可以做一些回复页面状态的工作,主要是数据,页面UI不用过多处理,WP7的墓碑机制会为你做
4、Deactivated事件、程序挂起是触发,比如你正玩微博,突然来电话了,微博程序会被挂起,你可以再事件中做一些临时数据保存的措施
以上是针对整个应用程序而言的,页面也有生命周期只是通常不被强调,其实也是很有用的,页面生命周期比较简单,主要是加载,卸载,而每个控件都有其加载和卸载状态,所以,页面的生命周期并不是完整意义上的生命周期,只是一种状态。开发人员可以根据页面的状态做一些相应的处理。
下面说一下页面中最有用的几个事件
Loaded和Unloaded事件,页面加载和卸载时触发,加载时可以处理一些数据(微软不建议这么做,因为这会是页面加载很卡,那些页面切换动画就无法流畅的运行,给人感觉就是突然一下就蹦出个页面),卸载时可以保存数据
OnBackKeyPress事件,按后退按钮时触发,微软官方对后退按钮的用法建议是,如果当前页面中有输入法之类的子操作,则将其关闭而不退出本页,如果没有的话,退出本页,返回前一页,如果当前是程序首页则退出程序。在OnBackKeyPress事件中我们可以做很多事前,比如判断页面中是否有弹出层,如果有,则不退出本页,只关闭弹出层,如果是程序首页,则弹出确认框,提升用户是否真的要退出程序。后退按钮有关页面跳转的机制基本如下图
如图,WP7是用栈来存储页面的,后退按钮永远返回前一个页面,也就是你从那个页面来就回那个页面去。
OnNavigatedFrom事件,当从此页面中跳转走时触发;
通过一个简单的例子看一下这几个事件的调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace ShengMingZhouQi
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
this.Unloaded += new RoutedEventHandler(MainPage_Unloaded);
}
int count = 0;
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
count += 1;
}
void MainPage_Unloaded(object sender, RoutedEventArgs e)
{
count = 0;
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
base.OnBackKeyPress(e);
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
if (count == 0)
{
////
}
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
count += 1;
MessageBox.Show(count.ToString());
base.OnNavigatedTo(e);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/NewPage.xaml", UriKind.Relative));
}
}
}
上述是MainPage.xaml中的代码,打开程序时,或者跳转到NewPage.xaml后在跳回来时,结果如下图
我们发现了,程序先调用OnNavigatedTo事件,再调用MainPage_Loaded,这事也情理之中的的事,一来是必须先到页面才能加载,而来,这MainPage也是Page内部的一部分,记载要到了页面才行
OnNavigatedFrom和Unloaded事件是反过来的,先调用OnNavigatedFrom再调用Unloaded,这里就不给图了
现在说一下程序状态恢复与保存
在程序挂起后再次被激活,页面状态是会被自动恢复的,这事WP7系统自己处理的,现在给MainPage.xaml添加一个Button和一个TextBlock,点击Button,改变TextBlock的Text为"ClickButton",运行结果如下图
在Application_Deactivated和Application_Activated事件里添加断点,点击模拟器上的Window键,显示手机的主菜单Application_Deactivated事件被触发,
点击回退按键,看到Application_Activated事件被触发,按F5,界面重新回到MainPage.xaml上
发现页面并不是初始化时的样子,也就是TextBlock值是"ClickButton",看到系统会帮你维护挂起的程序,并在重新机会时自动恢复其原来的状态。这就是墓碑机制。
但是如果你关闭程序,再次打开,那之前的状态时不可能给你保存的,因为墓碑机制只适用于挂起的程序,而非关闭的程序。这种情况你必须自己恢复,怎么恢复呢,那就要用刀独立存储了,关闭前,将的必要的内容保存起来,程序启动后再取出来,恢复现场,看下面的代码,使用IsolatedStorageFile做保存和恢复现场工作,IsolatedStorageSettings同样适用。
app.xaml.cs
// 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)
{
if (fileStorage.FileExists("newText.txt"))
{
//读取文件
StreamReader fileReader = null;
fileReader = new StreamReader(new IsolatedStorageFileStream("newText.txt", FileMode.Open, fileStorage));
//读取内容
string textFile = fileReader.ReadLine();
message = textFile;
fileReader.Close();
}
}
// 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)
{
if (fileStorage.FileExists("newText.txt"))
{
fileStorage.DeleteFile("newText.txt");
}
//创建一个txt文件的流
StreamWriter fileWriter = new StreamWriter(new IsolatedStorageFileStream("newText.txt", FileMode.OpenOrCreate, fileStorage));
//向文件中写出内容
fileWriter.WriteLine(message);
//关闭StreamWriter.
fileWriter.Close();
}
MainPage.xaml.cs
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
textBox1.Text = App.message;
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
App.message = textBox1.Text.ToString();
base.OnNavigatedFrom(e);
}
这样,当程序退出时,将textBox1的内容存储起来,当重新进入程序时在读出来。
运行效果就不用看了,自己运行试试吧
上面用到了IsolatedStorageFile 上一章将页面之间共享数据用的是IsolatedStorageSettings,两者略有不同
IsolatedStorageSettings允许你在一个字典中存储键/值对(注意,无需任何设定),然后再读取出来。这些数据会一直保存着,无论应用程序停止/启动,或者关机等等。除非你删除它,或者用户卸载你的应用程序,否则它一直存在。要记住的一点是在它被添加到字典中之前你无法读取它。
IsolatedStorageSettings 可提供一种将用户特定数据存储为本地 IsolatedStorageFile 中的键/值对的便捷方法。一种典型的用途是保存设置,例如,每页显示的图像数、页面布局选项等。
IsolatedStorageFile表示包含文件和目录的独立存储区。使用IsolatedStorageFile是一种让你可以在用户的设备中存储真实文件的机制。
该类使独立存储的虚拟文件系统抽象化。IsolatedStorageFile 对象对应于特定的独立存储范围,在该范围中存在由 IsolatedStorageFileStream 对象表示的文件。应用程序可以使用独立存储将数据保存在文件系统中这些数据自己的独立部分,而不必在文件系统中指定特定的路径。
虚拟文件系统的根位于物理文件系统上经过模糊处理的每用户文件夹中。由主机提供的每个唯一标识符都映射为不同的根,该根为每个应用程序提供它自己的虚拟文件系统。应用程序不能从它自己的文件系统导航到另一个文件系统中。
因为独立存储区在特定程序集的范围内,所以其他大多数托管代码都不能访问您的代码的数据(高度受信任的托管代码和管理工具可以从其他程序集访问存储区)。非托管代码可以访问任何独立存储区。
从上面的解释可以看出来,如果你想利用工具(如SETool)开查看保存的独立存储空间的文件,你最好用IsolatedStorageFile,因为他相当于是实际存在的都开发者管理的,因此可以使用SETool取出来,但IsolatedStorageSettings 是受系统管理的,开发者只能访问内容,不能获取其文件。还有就是本身就是要存为文件的数据,比如MP3,就要用IsolatedStorageFile,不解释。
他们的用法已经在上一章和本章列出来了,并不复杂。