应用程序耗电的实质,是所启用的硬件在消耗电量。
- 手机的耗电单元
- CPU: 应用处理器(Application Processor)和基带处理器(Base Band)
Soc(系统级芯片): GPU(图形处理单元),
Video Codec等 外设:wifi,BT, GPS,LCD等
- CPU: 应用处理器(Application Processor)和基带处理器(Base Band)
- 耗电情况
应用处理器(Application Processor) 40~60mA
GPU开启时会大于100mA
基带处理器(Base Band)3~5mA
通话时100~200mA
LCD 100mA
Wifi 100mA
BT 60mA
AP是ARM架构的处理器,用于运行Linux+Android系统;
BP用于运行实时操作系统(RTOS),通讯协议栈运 行于BP的RTOS之上
非通话时间,BP的能耗基本上在5mA左右,而AP只要处于非休眠状态,能耗至少在50mA以上,执行图形运算时会更高。另外 LCD工作时功耗在100mA左右,WIFI也在100mA左右。
一般手机待机时,AP、LCD、WIFI均进入休眠状态,这时Android中应用程序 的代码也会停止执行,只会有基带处理器(Base Band)的耗电。
摩托罗拉的里程碑手机为例,官方的参数如下:
锂电池(1400mAh) 通话时间450分钟 待机时间420小时
也就是说,通话时1400/(450/60) = 186.67mA
待机时 1400/420 = 3.33mA
省电的原则:按需并按最低标准使用硬件
WakeLock机制:
-
Android为了确保应用程序中关键代码的正确执行,提供了Wake Lock的API,使得应用程序有权限通过代码阻止AP进入休眠状态。
WakeLock阻止应用处理器(Application Processor)挂起,确保关键代码的运行,通过中断唤起应用处理器(Application Processor),可以阻止屏幕变暗。所有的WakeLock被释放后,系统会挂起。PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); WakeLock sCpuWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,"okTag"); if (sCpuWakeLock!= null) { sCpuWakeLock.release(); sCpuWakeLock = null; }
PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。
SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯
SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,允许关闭键盘灯
FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
ACQUIRE_CAUSES_WAKEUP:不会唤醒设备,强制屏幕马上高亮显示,键盘灯开启。有一个例外,如果有notification弹出的话,会唤醒设备。
ON_AFTER_RELEASE:WakeLock 被释放后,维持屏幕亮度一小段时间,减少WakeLock 循环时的闪烁情况
如果申请了partial wakelock,那么即使按Power键,系统也不会进Sleep,如Music播放时 如果申请了其它的wakelocks,按Power键,系统还是会进Sleep
但如果不领会Android设计者的意图而滥用Wake Lock API,为了自身程序在后台的正常工作而长时间阻止AP进入休眠状态,就会成为待机电池杀手。
Alarm Manager
AlarmManage有一个AlarmManagerService,该服务程序主要维护app注册下来的各类Alarm,并且一直监听Alarm设备,一旦有Alarm触发,或者是Alarm事件发生,AlarmManagerService就会遍历Alarm列表,找到相应的注册Alarm并发出广播
Alarm Manager会维持一个cpu的wake lock。这样能保证电话休眠时,也能处理alarm的广播。一旦alarm receiver的onReceive() 方法执行完,wake lock会迅速被释放。如果在receiver中开启一个service,有可能service还没启动,wake lock已经被释放了。所以此时要实现单独的wake lock策略。
有4种Alarm类型:
1)RTC_WAKEUP
在指定的时刻(设置Alarm的时候),唤醒设备来触发Intent。
2)RTC
在一个显式的时间触发Intent,但不唤醒设备。
3)ELAPSED_REALTIME
从设备启动后,如果流逝的时间达到总时间,那么触发Intent,但不唤醒设备。流逝的时间包括设备睡眠的任何时间。注意一点的是,时间流逝的计算点是自从它最后一次启动算起。
4)ELAPSED_REALTIME_WAKEUP
从设备启动后,达到流逝的总时间后,如果需要将唤醒设备并触发Intent。