在256MB低配WP设备上做好Tango应用开发的12条建议
程序员文章站
2022-03-03 13:33:18
...
自从Windows Phone “Tango”将手机的运行内存下限降低到256MB之后,业内人士纷纷质疑为普通Windows Phone开发的应用程序是否能够在这些低配设备上正常运行。关于这一点,微软此前已经在MSDN专门发布过一个专题。作为Windows Phone生态系统的重要合作伙伴,诺基亚为开发者提供了以下12个要点建议,保证其出品的应用程序在256MB内存的 Tango 手机上也能正常运行。
1、记得用Windows Phone模拟器的256MB内存模式调试程序
这个是理所当然的,不用多说了。诺基亚建议开发者把256MB模拟器设为默认选项,以免忙中出错。此外不要绝对信赖模拟器,还是要在真机上调试过才保险。
2、善用Memory Profiler内存管理工具
Windows Phone SDK 7.1 自带了Memory Profiler工具,通过它能够非常直观地查看应用程序在任何一个时间点的内存使用情况。
3、增加几行代码,判断当前设备是否为256MB运行内存的低配设备
如果开发者希望用一套代码适配高配、低配等多个平台,这条建议就比较重要。Windows Phone 7.5系统中有一个属性是单个应用程序可支配的最大内存空间,使用DeviceExtendedProperties.GetValue(“ApplicationWorkingSetLimit”)方法即可获取到这一数值。如果获取到的值小于90MB(精确数字为94371840字节),则说明该设备为低配设备,仅有256MB运行内存,开发者应该对某些功能进行屏蔽,以免产生异常。
4、不要使用PeriodicTask和ResourceIntensiveTasks类
256MB内存的低配设备不支持上述两种类,一旦调用将触发异常。至于为什么要禁用它们,原因很简单:一个低配手机,运行内存一共就只有256MB,其中操作系统本身要占用100MB左右,假设此时前台正在运行一个占用内存大概60MB的软件,后台挂了一个占用内存60MB的ResourceIntensiveTasks任务,这就已经合计220MB,非常接近内存极限,很容易导致系统崩溃。不过,用于后台音乐播放、文件传输、闹铃等功能的BackgroundTasks类在256MB内存设备上依旧可用。
5、少用<WebBrowser/>控件,多用WebBrowserTask类
<WebBrowser/>控件能够在应用程序内直接读取并显示任何网页。如果显示的网页是PC版,并且未针对手机进行优化,其占用的内存就可能非常大,在256MB内存设备上可能直接造成系统崩溃。而用WebBrowser就方便得多,网页将在浏览器内打开,当前运行的程序被切出(一定要记得做好墓碑机制),这样能节省不少内存。当然了,如果您为了好看,非得使用<WebBrowser/>控件,最好对用户可能访问的网页做一下限制,只允许访问经过测试并且不会造成内存溢出的网页。
6、用BingMapsTask代替<Map/>控件
<Map/>控件允许用户对地图进行拖曳、缩放等操作。我们知道Bing地图是无数块小图组成的,在用户反复拖拉缩放时,系统会不断创建新图片对象,导致内存占用飙升。实验表明,对一个<Map/>控件不断操作2分钟后内存占用达到50MB。这个数字在高配Windows Phone(可用运行内存90MB)完全不是问题,但是在低配手机(可用运行内存60MB)就已经接近极限。BingMapsTask产生的地图不允许用户随便操作,完全避免了内存溢出的可能性。
7、适当压缩图片
这个不用多说,图片越大占用的内存空间越大。反正Windows Phone的屏幕就是800×480那么大,哪怕十亿像素的原图,到手机屏幕上也不过自动缩放成那么一丁点,何必逼着一个低配手机小马拉大车呢?
8、用支持数据虚拟化ListBox代替篇幅超长而且带图片的数据列表
通俗的说,道理是这样的:我们已经知道在Windows Phone平台上每初始化一个图片对象就要占用一块额外内存。诺基亚在网站上提供了一段示例代码,在Flickr上搜索图片,并用列表的形式显示。随着用户不断滚动搜索结果列表,在Memory Profiler里看到的内存占用情况就成了这样:
用户一边滚动列表,程序一边从Flickr读取并显示新图片,系统就一边创建新的图片对象,然后内存占用就像爬楼梯一样很快到顶了。
这种时候有两种方法可以解决问题。第一种治标不治本:只显示Flickr的缩略图,每个图片的体积都变小了,但是滚动得久了还是要发出内存溢出。另外一种更合理的方法就是分页显示,比如说一页只显示10个结果。
9、禁用页面过渡动画
Windows Phone 7里面动画元素占据了很重要的地位,飞进飞出、旋转之类效果到处都有。这些动画效果可能占用大约5MB的运行内存。这个数字看起来很小,但是在可分配运行内存只有60MB的低配手机上就显得很大了。诺基亚做了一个启用和禁用过渡效果的内存占用情况对比图表:
美观和流畅孰轻孰重,请各位根据自己的项目需求自行定夺。
10、不要反复创建同一个SoundEffects
有些开发者(尤其是游戏开发者)每次触发声音事件时都要建立一个新的SoundEffects,即便反复触发同一事件也照创建不误,从来不考虑重用。这种情况在高配Windows Phone上不是问题,因为闲置的垃圾SoundEffect积累太多,系统就自动进行垃圾回收清理内存了。不过在低配设备上,程序可用的运行内存只有60MB,很可能在系统进行GC之前就已经造成内存溢出。声音之类的能重用就重用,不能重用记得释放吧。
11、XNA开发者可考虑压缩资源组(assets)
另外一种节省内存的思路:既然内存那么紧张,那就把里面的数据压缩一下好了。用DXT等压缩算法能够对载入内存的资源组进行压缩,牺牲一部分质量,换取运行效率。
12、仔细寻找并消灭内存泄露
内存泄露在所有系统、所有开发平台上都会出现,主要取决于开发者本身的代码质量。多多调试、考虑到各种使用场景,把内存泄露全都掐死在摇篮里吧!
1、记得用Windows Phone模拟器的256MB内存模式调试程序
这个是理所当然的,不用多说了。诺基亚建议开发者把256MB模拟器设为默认选项,以免忙中出错。此外不要绝对信赖模拟器,还是要在真机上调试过才保险。
2、善用Memory Profiler内存管理工具
Windows Phone SDK 7.1 自带了Memory Profiler工具,通过它能够非常直观地查看应用程序在任何一个时间点的内存使用情况。
3、增加几行代码,判断当前设备是否为256MB运行内存的低配设备
如果开发者希望用一套代码适配高配、低配等多个平台,这条建议就比较重要。Windows Phone 7.5系统中有一个属性是单个应用程序可支配的最大内存空间,使用DeviceExtendedProperties.GetValue(“ApplicationWorkingSetLimit”)方法即可获取到这一数值。如果获取到的值小于90MB(精确数字为94371840字节),则说明该设备为低配设备,仅有256MB运行内存,开发者应该对某些功能进行屏蔽,以免产生异常。
4、不要使用PeriodicTask和ResourceIntensiveTasks类
256MB内存的低配设备不支持上述两种类,一旦调用将触发异常。至于为什么要禁用它们,原因很简单:一个低配手机,运行内存一共就只有256MB,其中操作系统本身要占用100MB左右,假设此时前台正在运行一个占用内存大概60MB的软件,后台挂了一个占用内存60MB的ResourceIntensiveTasks任务,这就已经合计220MB,非常接近内存极限,很容易导致系统崩溃。不过,用于后台音乐播放、文件传输、闹铃等功能的BackgroundTasks类在256MB内存设备上依旧可用。
5、少用<WebBrowser/>控件,多用WebBrowserTask类
<WebBrowser/>控件能够在应用程序内直接读取并显示任何网页。如果显示的网页是PC版,并且未针对手机进行优化,其占用的内存就可能非常大,在256MB内存设备上可能直接造成系统崩溃。而用WebBrowser就方便得多,网页将在浏览器内打开,当前运行的程序被切出(一定要记得做好墓碑机制),这样能节省不少内存。当然了,如果您为了好看,非得使用<WebBrowser/>控件,最好对用户可能访问的网页做一下限制,只允许访问经过测试并且不会造成内存溢出的网页。
6、用BingMapsTask代替<Map/>控件
<Map/>控件允许用户对地图进行拖曳、缩放等操作。我们知道Bing地图是无数块小图组成的,在用户反复拖拉缩放时,系统会不断创建新图片对象,导致内存占用飙升。实验表明,对一个<Map/>控件不断操作2分钟后内存占用达到50MB。这个数字在高配Windows Phone(可用运行内存90MB)完全不是问题,但是在低配手机(可用运行内存60MB)就已经接近极限。BingMapsTask产生的地图不允许用户随便操作,完全避免了内存溢出的可能性。
7、适当压缩图片
这个不用多说,图片越大占用的内存空间越大。反正Windows Phone的屏幕就是800×480那么大,哪怕十亿像素的原图,到手机屏幕上也不过自动缩放成那么一丁点,何必逼着一个低配手机小马拉大车呢?
8、用支持数据虚拟化ListBox代替篇幅超长而且带图片的数据列表
通俗的说,道理是这样的:我们已经知道在Windows Phone平台上每初始化一个图片对象就要占用一块额外内存。诺基亚在网站上提供了一段示例代码,在Flickr上搜索图片,并用列表的形式显示。随着用户不断滚动搜索结果列表,在Memory Profiler里看到的内存占用情况就成了这样:
用户一边滚动列表,程序一边从Flickr读取并显示新图片,系统就一边创建新的图片对象,然后内存占用就像爬楼梯一样很快到顶了。
这种时候有两种方法可以解决问题。第一种治标不治本:只显示Flickr的缩略图,每个图片的体积都变小了,但是滚动得久了还是要发出内存溢出。另外一种更合理的方法就是分页显示,比如说一页只显示10个结果。
9、禁用页面过渡动画
Windows Phone 7里面动画元素占据了很重要的地位,飞进飞出、旋转之类效果到处都有。这些动画效果可能占用大约5MB的运行内存。这个数字看起来很小,但是在可分配运行内存只有60MB的低配手机上就显得很大了。诺基亚做了一个启用和禁用过渡效果的内存占用情况对比图表:
美观和流畅孰轻孰重,请各位根据自己的项目需求自行定夺。
10、不要反复创建同一个SoundEffects
有些开发者(尤其是游戏开发者)每次触发声音事件时都要建立一个新的SoundEffects,即便反复触发同一事件也照创建不误,从来不考虑重用。这种情况在高配Windows Phone上不是问题,因为闲置的垃圾SoundEffect积累太多,系统就自动进行垃圾回收清理内存了。不过在低配设备上,程序可用的运行内存只有60MB,很可能在系统进行GC之前就已经造成内存溢出。声音之类的能重用就重用,不能重用记得释放吧。
11、XNA开发者可考虑压缩资源组(assets)
另外一种节省内存的思路:既然内存那么紧张,那就把里面的数据压缩一下好了。用DXT等压缩算法能够对载入内存的资源组进行压缩,牺牲一部分质量,换取运行效率。
12、仔细寻找并消灭内存泄露
内存泄露在所有系统、所有开发平台上都会出现,主要取决于开发者本身的代码质量。多多调试、考虑到各种使用场景,把内存泄露全都掐死在摇篮里吧!