1) Battery Drain and Networking
对于手机程序,网络操作相对来说是比较耗电的行为。优化网络操作能够显著节约电量的消耗。在性能优化第1季里面有提到过,手机硬件的各个模块的耗电量是不一样的,其中移动蜂窝模块对电量消耗是比较大的,另外蜂窝模块在不同工作强度下,对电量的消耗也是有差异的。当程序想要执行某个网络请求之前,需要先唤醒设备,然后发送数据请求,之后等待返回数据,最后才慢慢进入休眠状态。这个流程如下图所示:
在上面那个流程中,蜂窝模块的电量消耗差异如下图所示:
从图示中可以看到,激活瞬间,发送数据的瞬间,接收数据的瞬间都有很大的电量消耗,所以,我们应该从如何传递网络数据以及何时发起网络请求这两个方面来着手优化。
1.1) 何时发起网络请求
首先我们需要区分哪些网络请求是需要及时返回结果的,哪些是可以延迟执行的。例如,用户主动下拉刷新列表,这种行为需要立即触发网络请求,并等待数据返回。但是对于上传用户操作的数据,同步程序设置等等行为则属于可以延迟的行为。我们可以通过Battery Historian这个工具来查看关于移动蜂窝模块的电量消耗。在Mobile Radio那一行会显示蜂窝模块的电量消耗情况,红色的部分代表模块正在工作,中间的间隔部分代表模块正在休眠状态,如果看到有一段区间,红色与间隔频繁的出现,那就说明这里有可以优化的行为。如下图所示:
对于上面可以优化的部分,我们可以有针对性的把请求行为捆绑起来,延迟到某个时刻统一发起请求。如下图所示:
经过上面的优化之后,我们再回头使用Battery Historian导出电量消耗图,可以看到唤醒状态与休眠状态是连续大块间隔的,这样的话,总体电量的消耗就会变得更少。
当然,我们甚至可以把请求的任务延迟到手机网络切换到WiFi,手机处于充电状态下再执行。在前面的描述过程中,我们会遇到的一个难题是如何把网络请求延迟,并批量进行执行。还好,Android提供了JobScheduler来帮助我们达成这个目标。
1.2) 如何传递网络数据
关于这部分主要会涉及到Prefetch(预取)与Compressed(压缩)这两个技术。对于Prefetch的使用,我们需要预先判断用户在此次操作之后,后续零散的请求是否很有可能会马上被触发,可以把后面5分钟有可能会使用到的零散请求都一次集中执行完毕。对于Compressed的使用,在上传与下载数据之前,使用CPU对数据进行压缩与解压,可以很大程度上减少网络传输的时间。
想要知道我们的应用程序中网络请求发生的时间,每次请求的数据量等等信息,可以通过Android Studio中的Networking Traffic Tool来查看详细的数据,如下图所示:
2) Wear & Sensors
在Android Wear上会大量的使用Sensors来实现某些特殊功能,如何在尽量节约电量的前提下利用好Sensor会是我们需要特别注意的问题。下面会介绍一些在Android Wear上的最佳实践典范。
尽量减少刷新请求,例如我们可以在不需要某些数据的时候尽快注销监听,减小刷新频率,对Sensor的数据做批量处理等等。那么如何做到这些优化呢?
- 首先我们需要尽量使用Android平台提供的既有运动数据,而不是自己去实现监听采集数据,因为大多数Android Watch自身记录Sensor数据的行为是有经过做电量优化的。
- 其次在Activity不需要监听某些Sensor数据的时候需要尽快释放监听注册。
- 还有我们需要尽量控制更新的频率,仅仅在需要刷新显示数据的时候才触发获取最新数据的操作。
- 另外我们可以针对Sensor的数据做批量处理,待数据累积一定次数或者某个程度的时候才更新到UI上。
- 最后当Watch与Phone连接起来的时候,可以把某些复杂操作的事情交给Phone来执行,Watch只需要等待返回的结果。
更对关于Sensors的知识,可以点击这里。
3) Smooth Android Wear Animation
Android Material Design风格的应用采用了大量的动画来进行UI切换,优化动画的性能不仅能够提升用户体验还可以减少电量的消耗,下面会介绍一些简单易行的方法。
在Android里面一个相对操作比较繁重的事情是对Bitmap进行旋转,缩放,裁剪等等。例如在一个圆形的钟表图上,我们把时钟的指针抠出来当做单独的图片进行旋转会比旋转一张完整的圆形图的所形成的帧率要高56%。
另外尽量减少每次重绘的元素可以极大的提升性能,假如某个钟表界面上有很多需要显示的复杂组件,我们可以把这些组件做拆分处理,例如把背景图片单独拎出来设置为一个独立的View,通过setLayerType()方法使得这个View强制用Hardware来进行渲染。至于界面上哪些元素需要做拆分,他们各自的更新频率是多少,需要有针对性的单独讨论。
如何使用Systrace等工具来查看某些View的渲染性能,在前面的章节里面有提到过,感兴趣的可以点击这里。
想要获取更多关于Android Wear中动画效果的优化,请点击WatchFace这个范例。
4) Android Wear Data Batching
在Android Training里面有关于Wear上面如何利用Wearable API与Phone进行沟通协作的课程(详情请点击这里)。因为Phone的CPU与电量都比Wear要强大,另外Phone还可以直接接入网络,而Wear要接入网络则相对更加困难,所以我们在开发Wear应用的时候需要尽量做到把复杂的操作交给Phone来执行。例如我们可以让Phone来获取天气信息,然后把数据返回Wear进行显示。更进一步,在之前的性能优化课程里面我们有学习过如何使用JobScheduler来延迟批量处理任务,假设Phone收到来自Wear的其中一个任务是每隔5分钟检查一次天气情况,那么Phone使用JobScheduler执行检查天气任务之后,先判断这次返回的结果和之前是否有差异,仅仅当天气发生变化的时候,才有必要把结果通知到Wear,或者仅仅把变化的某一项数据通知给Wear,这样可以更大程度上减少Wear的电量消耗。
下面我们总结一下如何优化Wear的性能与电量:
- 仅仅在真正需要刷新界面的时候才发出请求
- 尽量把计算复杂操作的任务交给Phone来处理
- Phone仅仅在数据发生变化的时候才通知到Wear
- 把零碎的数据请求捆绑一起再进行操作