Android6.0以后引入了Doze和Standby省电模式,看了下源码,主要体现在DeviceIdle服务中。
DeviceIdle采用了定时器驱动的状态机方式来推进不同状态之间的变化。状态变化如下图:
状态变化
下面对照图详细展开来说。
先看一下nexus6p实际dumpsys的结果:
# dumpsys deviceidle
Settings:
inactive_to=+30m0s0ms
sensing_to=+60s0ms
locating_to=+15s0ms
location_accuracy=20.0m
motion_inactive_to=+10m0s0ms
idle_after_inactive_to=+30m0s0ms
idle_pending_to=+5m0s0ms
max_idle_pending_to=+10m0s0ms
idle_pending_factor=2.0
idle_to=+60m0s0ms
max_idle_to=+6h0m0s0ms
idle_factor=2.0
min_time_to_alarm=+60m0s0ms
max_temp_app_whitelist_duration=+5m0s0ms
mms_temp_app_whitelist_duration=+60s0ms
sms_temp_app_whitelist_duration=+20s0ms
Whitelist (except idle) system apps:
com.android.providers.downloads
Whitelist (except idle) all app ids:
10006
mEnabled=false
mForceIdle=false
mSigMotionSensor={Sensor name="Significant motion", vendor="Google", version=1, type=17, maxRange=1.0, resolution=1.0, power=0.0, minDelay=-1}
mCurDisplay=Display id 0: DisplayInfo{"内置屏幕", uniqueId "local:0", app 1440 x 2392, real 1440 x 2560, largest app 2392 x 2308, smallest app 1440 x 1356, mode 1, defaultMode 1, modes [{id=1, width=1440, height=2560, fps=60.0}], colorTransformId 1, defaultColorTransformId 1, supportedColorTransforms [{id=1, colorTransform=-22}], rotation 0, density 560 (515.154 x 516.063) dpi, layerStack 0, appVsyncOff 0, presDeadline 17666667, type BUILT_IN, state ON, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}, DisplayMetrics{density=3.5, width=1440, height=2392, scaledDensity=3.5, xdpi=515.154, ydpi=516.063}, isValid=true
mScreenOn=true
mCharging=true
mSigMotionActive=false
mSensing=false mNotMoving=false
mLocating=false mHaveGps=false mLocated=false
mState=ACTIVE
mInactiveTimeout=+30m0s0ms
结果中输出了很多定时器的时间,这些时间也体现在上图中。
最核心的状态就是Idle和Idle maintenance,在这个两个状态发生切换时,会通知其他服务,比如powerManager, networkManger,进行相应的服务限制或者放行。