PowerManager提供的WakeLock封装了不同级别的亮灭屏方案,其中就包括PROXIMITY_SCREEN_OFF_WAKE_LOCK ,此类型WakeLock,会开启距离传感器触发近距离自动灭屏。
打开就是WakeLock.acquire,关闭就是WakeLock.release。 示例代码如下:
WakeLOCK类别
WakeLock 分类如下:
- PARTIAL_WAKE_LOCK: 灭屏,关闭键盘背光的情况下,CPU依然保持运行。
- PROXIMITY_SCREEN_OFF_WAKE_LOCK: 基于距离感应器熄灭屏幕。最典型的运用场景是我们贴近耳朵打电话时,屏幕会自动熄灭。
- SCREEN_DIM_WAKE_LOCK/SCREEN_BRIGHT_WAKE_LOCK/FULL_WAKE_LOCK:这三种WakeLock都已经过时了,它们的目的是为了保持屏幕长亮,Android官方建议用
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
方式替换。因为比起申请WakeLock,这种方式更简单,还不需要特别申请android.permission.WAKE_LOCK
权限。 - DOZE_WAKE_LOCK/DRAW_WAKE_LOCK: 隐藏的分类,系统级别才会用到。DreamManagerService 会申请DOZE_WAKE_LOCK。WindowsManagerService 中的WindowsState.java会申请DRAW_WAKE_LOCK。
建议供用户使用的是这两个:PARTIAL_WAKE_LOCK和PROXIMITY_SCREEN_OFF_WAKE_LOCK。
再往下代码调用路径是WakeLock.acquire()->WakeLock.qcquireLocked()->IPowerManager.acquireWakeLock()
到这里就走到了PowerManagerService。具体如何实现呢?这就要看PowerManagerService.java。
PowerManagerService.acquireWakeLock
在这里针对PROXIMITY_SCREEN_OFF_WAKE_LOCK的acquireWakeLock过程分析。
PowerManagerService log分析
adb命令查询
adbshell dumpsys power|grep -i wake》》
no_cached_wake_locks=true
mWakefulness=Awake
mWakefulnessChanging=false
mWakeLockSummary=0x1
mLastWakeTime=29887736 (66197 ms ago)
mHoldingWakeLockSuspendBlocker=true
mWakeUpWhenPluggedOrUnpluggedConfig=true
mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig=false
mDoubleTapWakeEnabled=false
Wake Locks: size=5
PARTIAL_WAKE_LOCK 'AudioMix' ACQ=-1s287ms (uid=1041)
PARTIAL_WAKE_LOCK 'ImsPhoneConnection' ACQ=-1s232ms (uid=1001 pid
=2196)
PARTIAL_WAKE_LOCK 'AudioMix' ACQ=-1s128ms (uid=1041)
PARTIAL_WAKE_LOCK 'AudioMix' ACQ=-1s124ms (uid=1041)
PARTIAL_WAKE_LOCK 'AudioMix' ACQ=-1s123ms (uid=1041)
PowerManagerService.WakeLocks: ref count=1
log,匹配PowerManagerService关键字。如果想看更多的log需要在PowerManagerService.java文件中把debug开关打开。
参考链接:
https://www.jianshu.com/p/5abd53abcc1e Android battery historian功耗分析之环境搭建