Windows Phone 7 开发经验总结
1. 有关NavigationService的函数调用语句不能放到页面的构造函数里,否则会提示对象空引用异常。
例如:NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.RelativeOrAbsolute));
同样,如果想取得this.NavigationContext.QueryString也是会报错的。
这些语句不能直接放到页面构造函数里,或者间接的放在一个自定义函数里,然后在页面构造函数里调用此自定义函数也不行。
解决办法是: 只能放在OnNavigatedTo()方法里。
2.关于PhotoResult类型对象的使用技巧
当CameraCaptureTask拍完照后会将照片放在一个PhotoResult类型的对象中,
1.读取PhotoResult的OriginalFileName属性可以取得文件保存路径;
2.读取PhotoResult的ChosenPhoto属性可以得到文件的stream
在这种情况下,有两种办法可以显示和处理照片文件stream:
a. 创建一个BitmapImage对象,将ChosenPhoto作为参数赋值给BitmapImage对象的SetSource()方法,例如
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto); //PhotoResult e;如果想在界面上显示照片,可以创建一个Image控件,将bmp赋值给Image对象的Source属性,例如
Image img = new Image();
img.Source = bmp;如果想对照片进行图像处理,比如改变大小,改变色调,等等,可以将BitmapImage对象转换为WriteableBitmap类型,例如
WriteableBitmap img0 = new WriteableBitmap(bitmap);
然后就可以对img0进行各种处理。
b. 还可以将照片stream通过PictureDecoder对象转换成WriteableBitmap 对象,然后进行各种处理,例如WriteableBitmap img0 = PictureDecoder.DecodeJpeg(PhotoResult.ChosenPhoto);
但是,在做这步之前必须将stream重新定位到起始位置,否则会报错
PhotoResult.ChosenPhoto.Seek(0, System.IO.SeekOrigin.Begin);
3. 关于WP7的LifeCycle
WP7程序有四种状态: Launching, Deactivated, Activated, Closing
引发它们的时机如下表所示:
状态 |
引发时机 |
Launching |
用户从程序安装列表里选择并执行 |
Deactivated |
1. 用户按下“start”键,启动了另一个程序 2. 程序调用了Task应用(例如:CameraCaptureTask) |
Activated |
1. 用户启动另一个程序,然后又多次按下“Back”键,从而又切换回你的程序 2. 程序退出了Task应用,返回到你的程序 |
Closing |
在程序的主页面按下“Back”键 |
经过试验发现,对于需要执行初始化才能使用的全局变量,不会受到Task应用切换的影响,也就是说,Task应用的切换导致程序状态在Deactivated和Activated之间切换,但是,全局变量不需要在Activated时重新初始化。
但是,如果是用户通过按“start”键和“Back”键在两个应用程序之间进行状态切换,这样虽然同样是在Deactivated和Activated之间切换,但是,全局变量必须在Activated时重新初始化,否则变量为null, 不能使用.
因此,综上所述,对于需要执行初始化才能使用的全局变量,在Launching和Activated状态发生时都必须执行一次初始化。
4. 关于程序部署
XAP文件实际上就是压缩的zip格式,可以用解压软件打开看。可以发现里面的文件和目录都与你在工程里实际设置是一样的。需要注意的是,我们经常会自定义一些子目录,将程序需要的一些数据库文件,图片文件或者其他设置文件放在子目录中,但是一旦程序被更新,例如安装新版本,那么这些文件和目录都将会被删除。所以,如果你有一些数据文件是不允许在安装新版本时被删除的,那么就只有将它放在IsolatedStorage里,放在这里的文件除非卸载程序,否则不会被删除(即使更新程序版本)。
5. 对象删除节约内存
WP7上一个应用程序可使用的内存不能超过90M,否则程序会自动退出并且不报任何异常信息。
同时,WP7上使用image会占用大量内存,不论是在UI上添加Image控件还是为Panorama控件设置图像背景,
因此,为了节约内存,可以在需要的时候手动释放不再需要的Image控件,如果你觉得垃圾收集不好用的话。
下面三种方法都能释放内存,但是第一种方法并没有完全释放,还保存了几十K的信息,估计是用于恢复图像显示的。
1. img_Logo.Visibility = System.Windows.Visibility.Collapsed;
2. LayoutRoot.Children.Remove(img_Logo);
3. img_Logo.Source = null;
注意:如果Image是在XAML文件里定义的,则用上述方法是不起作用的。