HttpResponseCache
的缓存数据:第一种方式是缓存溢出的时候删除最旧最老的文件,第二种方式是通过Http返回Header中的Cache-Control
字段来进行控制的应用程序的一个基础功能是能够保持确保界面上呈现的信息是即时最新的,例如呈现最新的新闻,天气,信息流等等信息。但是,过于频繁的促使手机客户端应用去同步最新的服务器数据会对性能产生很大的负面影响,不仅仅使得CPU不停的在工作,内存,网络流量,电量等等都会持续的被消耗,所以在进行网络请求操作的时候一定要避免多度同步操作。
退到后台的应用为了能够在切换回前台的时候呈现最新的数据,会偷偷在后台不停的做同步的操作。这种行为会带来很严重的问题,首先因为网络请求的行为异常的耗电,其次不停的进行网络同步会耗费很多带宽流量。
为了能够尽量的减少不必要的同步操作,我们需要遵守下面的一些规则:
- 首先我们要对网络行为进行分类,区分需要立即更新数据的行为和其他可以进行延迟的更新行为,为不同的场景进行差异化处理。
- 其次要避免客户端对服务器的轮询操作,这样会浪费很多的电量与带宽流量。解决这个问题,我们可以使用Google Cloud Message来对更新的数据进行推送。
- 然后在某些必须做同步的场景下,需要避免使用固定的间隔频率来进行更新操作,我们应该在返回的数据无更新的时候,使用双倍的间隔时间来进行下一次同步。
- 最后更进一步,我们还可以通过判断当前设备的状态来决定同步的频率,例如判断设备处于休眠,运动等不同的状态设计各自不同时间间隔的同步频率。
关于提升网络操作的性能,除了避免频繁的网络同步操作之外,还可以使用捆绑批量访问的方式来减少访问的频率,为了达到这个目的,我们就需要了解Prefetching。
一个比较普适的规则是,在3G网络下可以预取1-5MB的数据量,或者是按照提前预期后续1-2分钟的数据作为基线标准。在实际的操作当中,我们还需要考虑当前的网络速度来决定预取的数据量,例如在同样的时间下,4G网络可以获取到12张图片的数据,而2G网络则只能拿到3张图片的数据。所以,我们还需要把当前的网络环境情况添加到设计预取数据量的策略当中去。判断当前设备的状态与网络情况,可以使用前面提到过的 GCMNetworkManager 。- A)首先需要做的是减少图片的大小,选择合适的图片保存格式是第一步。下图展示了PNG,JPEG,WEBP三种主流格式在占用空间与图片质量之间的对比:
对于JPEG与WEBP格式的图片,不同的清晰度对占用空间的大小也会产生很大的影响,适当的减少JPG Quality,可以大大地缩小图片占用的空间大小。
另外,我们需要为不同的使用场景提供当前场景下最合适的图片大小,例如针对全屏显示的情况我们会需要一张清晰度比较高的图片,而如果只是显示为缩略图的形式,就只需要服务器提供一个相对清晰度低很多的图片即可。服务器应该支持到为不同的使用场景分别准备多套清晰度不一样的图片,以便在对应的场景下能够获取到最适合自己的图片。这虽然会增加服务端的工作量,可是这个付出却十分值得!
- B)其次需要做的是减少序列化数据的大小。JSON与XML为了提高可读性,在文件中加入了大量的符号,空格等等字符,而这些字符对于程序来说是没有任何意义的。我们应该使用Protocal Buffers,Nano-Proto-Buffers,FlatBuffer来减小序列化的数据的大小。
使用Service应该遵循下面的一些规则:
- 避免错误的使用Service,例如我们不应该使用Service来监听某些事件的变化,不应该搞一个Service在后台对服务器不断的进行轮询(应该使用Google Cloud Messaging)
- 如果已经事先知道Service里面的任务应该执行在后台线程(非默认的主线程)的时候,我们应该使用IntentService或者结合HanderThread,AsycnTask Loader实现的Service。
Perf Theory: Approximation(近似法)
很多时候,我们都需要学会在性能更优与体验更好之间做一定的权衡取舍。为了获取更好的表现性能,我们可能会需要牺牲一些用户体验,例如把某些细节做删除或者是降级处理以便有更好的性能。例如,导航类的应用,如果在导航期间是不停的执行定位的操作,这样能够很及时的获取到最新的位置信息以及当下位置相关的其他提示信息,但是这样会导致网络流量以及手机电量的过度消耗。所以我们可以做一定的降级处理,每隔固定的一段时间才去获取一次位置信息,损失一点及时性来换取更长的续航时间。
还有很多地方都会用到近似法则来优化程序的性能,例如使用一张比较接近实际大小的图片来替代原图,换取更快的加载速度。所以对于那些对计算结果要求不需要十分精确的场景,我们可以使用近似法则来提高程序的性能。
Perf Theory: Culling(遴选,挑选)
在以前的性能优化课程里面,我们知道可以通过减少Overdraw来提高程序的渲染性能(主要手段有移除非必须的background,减少重叠的布局,使用clipRect来提高自定义View的绘制性能),今天在这里要介绍的另外一个提高性能的方法是逐步对数据进行过滤筛选,减小搜索的数据集,以此提高程序的执行性能。例如我们需要搜索到居住在某个地方,年龄是多少,符合某些特定条件的候选人,就可以通过逐层过滤筛选的方式来提高后续搜索的执行效率。
Perf Theory: Threading
使用多线程并发处理任务,从某种程度上可以快速提高程序的执行性能。对于Android程序来说,主线程通常也成为UI线程,需要处理UI的渲染,响应用户的操作等等。对于那些可能影响到UI线程的任务都需要特别留意是否有必要放到其他的线程来进行处理。如果处理不当,很有可能引起程序ANR。关于多线程的使用建议,可以参考官方的培训课程http://developer.android.com/training/best-background.html
数据序列化及网络传输:
数据序列化的行为可能发生在数据传递过程中的任何阶段,例如网络传输,不同进程间数据传递,不同类之间的参数传递,把数据存储到磁盘上等等。通常情况下,我们会把那些需要序列化的类实现Serializable接口(如下图所示),但是这种传统的做法效率不高,实施的过程会消耗更多的内存。三个数据序列化的候选方案:
- Protocal Buffers:强大,灵活,但是对内存的消耗会比较大,并不是移动终端上的最佳选择。
- Nano-Proto-Buffers:基于Protocal,为移动终端做了特殊的优化,代码执行效率更高,内存使用效率更佳。
- FlatBuffers:这个开源库最开始是由Google研发的,专注于提供更优秀的性能。