如今电子设备的发展越来越偏向于移动化,对于每个移动设备用户来讲:设备的电量都是最为宝贵的资源,可是直到今天我们几乎每天都要给自己的移动设备进行充电,每天都要花一部分时间用在给电池补充资源上;这实在是一件令人沮丧的事情。
同时对于大部分开发商或者开发人员,电池效率往往是他们最后考虑事情。所以这也让我们的移动设备电量消耗更快。
然而你的应用程序事实上没有必要成为耗电的那一个,使用几个简单的API和工具就能让你开发出受用户喜爱、更低耗电量的应用。
一、Android系统真的耗电吗
当你的移动设备忙于处理各项任务时,这些硬件工作会有效的消耗你的手机电量。正如我们所见:设备要做的工作越多电量消耗越大。
要写出小的耗电量的应用关键在于:一定要透彻理解,手机内部各个硬件模块的工作原理是什么?以及我们应用哪些任务消耗电量最多?然而这个问题并不是那么容易回答的,因为本身记录耗电的任务也会带来电量消耗。所以一般设备都没有这个功能。
手机消耗电量获取的最佳方式是:接入第三方硬件到你的Android设备,这个第三方硬件进行录但是不使用手机的电量。
Google也对自己的产品Nexus5为例:在飞行模式下,将设备放在桌子上不用去管它,直到电池电量消耗殆尽可以维持近一个月的时间。我们可以把这个当成电池寿命的基准线。所以耗电这个问题还真不能怪Android系统。
但这不属于设备的典型应用场景,一旦用户开始活跃的使用设备,就会消耗更多的电量
比如:CPU、蜂窝、WIFI数据交换、屏幕保持唤醒等状态。
二、应用真的耗电吗
现在的电池使用情况有多差?有机构做过一项调查:关于移动设备上的应用和游戏的调查;测量过他们在各种活动下的耗电量。然后发现这些应用的耗电量中平均只有25% — 35%是用于应用的核心功能的;比如图形绘制、新闻显示等;剩下的75%完全消耗在上传数据、检查位置和持续性的从服务器获取广告来展示。
这些应用正在为了自身利益而消耗用户的电量,但却只为用户提供了一小部分功能。然而用户结束一天的行程,手机电量却早早的消耗殆尽,这很容易影响到用户的心情。当你的设备电量消耗殆尽时,你拿着的也只是一个高精度的板砖。
三、查看应用耗电
还好Android有几个工具可以帮助追踪并解决这些电量问题。首先我们可以在手机电池上获取电池数据:通过设置—电池,然后选择你想要了解的应用,你会看到该应用的数据报告。
它主要的还是关于设备被唤醒的时间还有它的网络活动,你还可以使用BatteryHistorian工具来深入挖掘信息:得到你的应用实时消耗电量的可视图形文件。
一旦你发现应用的问题,Android有几个API可以帮助你修复这些问题。例如使用JobScheduler API,可允许你的应用来区分不同类型的工作,以便在更理想的状态下工作,如接入电源时、连接WIFI时或者下次用户主动唤醒屏幕时。
四、Battery Historian
通过该工具允许你创建一条时间线,使我们很容易就看到每一项任务的频率,通过分析这些信息能够有助于为你的电池优化指定目标。
荐:https://blog.csdn.net/chenliguan/article/details/53454590
1、如何生成电量消耗报告单
先关闭adb服务,再开启adb服务
(a)adb kill-server
(b) adb kill-start
重置电池数据,这一步主要为去除干扰项
(c)adbshell dumpsys batterystats--enable full-wake-history
(d)adbshell dumpsys batterystats--reset
获取电量报告
android6.0以下设备:
(e)adb bugreport bugreport.txt
android7.0以上设备:
(e)adb bugreport > bugreport.txt
或者用下面命令也可以,直接输出想要的信息:
(e.1)adb shell dumpsys batterystats > batterystats.txt
(e.2)adb shell dumpsys batterystats > packageName > batterystats.txt
使用下载好的python
(f)python historian.py -a bugreport.txt > battery.html
最后使用Google浏览器打开:
如下图所示:
historian.py脚本是Python写的,所以需要historian脚本,文件在github上面的scripts目录下面,需要下载到命令行所在的目录:
https://github.com/google/battery-historian
2、Battery History报告中参数的意义
横坐标:
上面的35 、40代表秒,以1分钟为一个周期,到60s就变为0。它就代表了一个时间的范围。
纵坐标:
纵坐标的内容就非常多了,在这只给大家介绍几个重要的参数:
battery_level:
电量,可以看出电量的变化。比如上图中的数据显示刚开始电量是100%,然后在后面一段时间内未发生掉电情况。
screen :
屏幕是否点亮,这一点可以考虑到睡眠状态和点亮状态下电量的使用信息。
wake_lock*:
wake_lock 该属性是记录wake_lock模块的工作时间。是否有停止的时候等。
Job :
后台的工作,比如服务service的运行。可以看到当前没有任何服务在工作。
GPS:
gps是否开启。
......
Battery History主要是为我们提供一条时间线,然后可以依据battery_level查看掉电情况,然后如果在某一时间段内掉电频率较高,那可以依次查找在该时间段内在执行哪些任务。如:一直在上传坐标信息等。
五、寻找平衡点
先来看下问题:
1、唤醒休眠中的设备需要消耗相应的电量。同时更加灵活的使用唤醒锁也可以帮助减少电量消耗。
2、使用蜂窝进行无线网络连接是移动设备上影响电池性能的头号杀手。而你传输的数据越多付出的成本和代价也就越多。
3、定期的轮询服务器更新是绝对不可取的,这种情况下基本上是浪费带宽和电量让服务器告诉你什么都没有改变。
为此:
1、减少无线电活跃的时间。
2、减少你获取数据的大小。
3、减少网络请求的频次。
但是降低请求数量实际上是一个复杂的公式,从更容易方向出发我们可以将其分为3个基本类型:
1、用户要求你做的时候。
2、是服务器要求对你更新的时候。
3、需要频繁上传的数据。比如位置。
其中2和3是我们需要优化的重点。
为此有人想要更好的解决方案:怎样在消耗更少电量的情况下实现同样的性能,这将专注于寻找一个平衡点。
聪明的人会让这两种极端情况回到一个平衡点上:
1、减少应用后台处理逻辑
应用程序即使在后台做大量的逻辑计算也会使CPU得不到休息,当我们的应用进入后台时主动释放这部分资源占用。
2、延迟处理
通常情况下,移动数据网络要比WIFI网络更加耗电,对于非及时性任务可以延迟处理,即在WIFI环境下执行,另外也可以监听手机充电状态时再执行任务。
例如:分析和统计之类的非重要操作,可以在合适状态(电量充足或Wifi状态)下发送。
3、合并任务
网络请求是非常消耗电量的,减少网络请求则很有助于减少电量消耗。
例如:对多个小的子任务可以合并成一个任务完成数据发送。
4、及时关闭不在需要的功能
要注意当你要执行的任务结束时,主动释放weakLock,这点非常重要,休眠可以保存电池电量;如果你忘记了让设备休眠,或者长时间保持不锁屏的状态会迅速消耗电池量。
另外蜂窝式无线也是耗电量非常可怕的,每当你的设备通过无线网发送数据时为了让硬件准备投入使用,这里会出现一个唤醒点高峰,数据包的发送和接受的过程都是非常耗电的。硬件在完成任务时,会在一小段时间内保持开启,防止短时间内还有数据包需要接收。
5、谨慎地使用WeakLock
Android为了节省电量,会在用户无操作一段时间之后进入休眠状态。Wake Lock是一种锁的机制,只要有人拿着这个锁,系统就无法进入休眠。一些App为了能在后台持续做事情,就会持有一个WakeLock,那么手机就不会进入休眠状态,App要做的事情能做了,但是也更加耗电。
App在前台不要申请WakeLock,此时无需申请,申请的话会计算到应用电量消耗;
App在后台由于业务需要必须要申请WakeLock时使用带有超时参数的方法,防止由于忘记或者异常情况下没有释放;
App申请使用WakeLock,任务结束之后及时释放,让系统再次进入休眠状态。
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG);wl.acquire(15000);// 使用带有超时参数的acquire方法// ... do work...endwl.release();
6、使用JobScheduler
使用JobScheduler,一些任务通过JobScheduler来触发,例如可推迟的网络请求、下载、GPS等,可以在特定场景:连接Wifi、连接电源等场景触发。既完成了任务,也无需考虑由于一些任务导致的电量消耗。
六、总结
实际上电量优化与业务功能总是矛盾的,比如视频类应用在观看视频时那它此时耗电就是较高的。总不能在一段时间上提醒用户让手机休息一下吧?
另外通过软件分析电量消耗可靠性不大,只能说记住那几个点,在写代码是注意这几个点:
a、减少,减少应用后台处理的逻辑。
b、延迟,当设备充电时或者WIFI情况下再去执行。
c、合并,将多个任何合并成一个进行处理。
d、及时关闭不再需要的功能:如GPS,网路请求超时设置
Android5.0之后系统为我们提供了JobScheduler,JobScheduler由系统完成调用,这样手机中所有app实行统一调度任务。