测试Doze和待机模式

11

我关闭了运行Android M的Nexus 5设备的屏幕显示,然后发出了以下命令。

im17-x0:~ r.j$ adb shell dumpsys battery unplug
im17-x0:~ r.j$ adb shell dumpsys deviceidle step
Stepped to: IDLE_PENDING
im17-x0:~ r.a$ adb shell dumpsys deviceidle step
Stepped to: SENSING
im17-x0:~ r.a$ adb shell dumpsys deviceidle step
Stepped to: IDLE

现在理想情况下我的设备应该进入空闲模式。但是我在将其置于空闲模式之前启动了一个CountDownTimer,它仍在运行。同时,我的手机上仍然有网络访问(使用this函数进行检查)。
为什么设备没有进入待机模式?按照此处的选项进行待机模式也有相同的效果。为什么?
另外,在那个计时器中,如果我检查isDeviceIdleMode(),它会返回true。

1
你明白这种行为的原因了吗?我也有一个类似的用例,我的计时器似乎在运行,不受Doze模式的影响。但是isDeviceIdleMode()在日志中返回true。 - Mithil Jadhav
5个回答

1

Here is some useful information on Idle Mode:

deviceidle - Is a new android service, that will always run and listen for the several system events, which can trigger it in/out of the idle mode (also known as a Doze mode):

1.Screen on/off
2.Charging status
3.Significant motion detect

DeviceIdleController - When the device is awake and in-use, the controller is in the ACTIVE state. External events like inactivity time-out, user powering off the screen, motion detection ... will drive the state machine into INACTIVE. This state machine contains seven states:

1.ACTIVE - Device is in use, or connected to a charge source.
2.INACTIVE - Device has recently come out of the active state, meaning that user turned off the display or unplugged it.
3.IDLE_PENDING - Hold on, we are about to enter idle mode.
4.SENSING
5.LOCATING
6.IDLE - Device is idle.
7.IDLE_MAINTENANCE - Window is open for applications to do processing. Then will back to IDLE.

Idle State - In order to put the device into an Idle state you can use the following adb commands:

>adb shell dumpsys battery unplug
>adb shell dumpsys deviceidle force-idle

Active State - In order to put the device back into the Active state you may simulate the following key event:

> adb shell input keyevent KEYCODE_WAKEUP

I also needed a quick option to toggle between Active and Idle states so I wrote a batch script adbIdleModeSwitch.bat for these purposes, you may download and use it: https://drive.google.com/file/d/0B81qFnPX_eUUYTMxOTd1UG94NVk/view


我尝试了命令 adb shell dumpsys deviceidle force-idleadb shell input keyevent KEYCODE_WAKEUP,认为它们没有任何效果。结果发现第一个命令需要一两分钟后才能生效。 - Giszmo

1
我给你几个提示:
网络访问
我建议通过实际尝试网络调用并记录日志来测试网络访问。在空闲模式下编程检查网络访问存在已知的错误:https://code.google.com/p/android-developer-preview/issues/detail?id=3164 检查空闲/Doze模式
虽然没有太多文档,但有一些方法不受Doze模式的影响。使用CountDownTimer可能是其中之一。我建议使用setExact()设置一个闹钟,因为已有文档证明当应用处于空闲模式时它不起作用。如果你能在闹钟触发时记录一些内容,那么你肯定不是处于空闲模式。
请告诉我这对你有什么帮助!

1
目前,该行为如下:
  1. isDeviceIdleMode() 将返回 true。
  2. 应用中的网络可用性检查始终返回 true。(使用 this 函数进行检查)
  3. 当设备进入和退出待机模式时,网络没有任何变化(没有网络广播被触发)。但是,当设备进入和退出待机模式时会触发一个广播(待机广播)。
  4. 然而,在待机模式下我们无法进行网络调用。(尝试使用 HttpUrlConnection
关于在待机模式下返回 true 的 getNetworkInfo(),Android 中已报告了一个 bug(Link)。

晚回复,但是...第三点:你说的没有变化是什么意思?我现在正在开发MM版本,将我的华为Mate 7更新到了MM版本,并发现设备一旦进入待机模式,网络就会发生变化。我在我的应用程序上做了一些日志记录,发现从Wifi连接到移动连接再返回来。这是华为实现的一个bug还是正常的MM行为? - Opiatefuchs
1
@Opiatefuchs 我认为他的意思是任何现有的TCP连接不会自动终止并继续报告已连接,但无法传输或接收数据。 - behelit

0

重写: 我最初的答案假设您的设备实际上并不处于Doze模式,因此提供了改进的进入Doze模式指南深入Android 'M' Doze关于IDLE_MAINTENANCE状态的链接,其中允许运行网络活动。

我的新假设是(1)当deviceidle step回复Stepped to: IDLE时,设备处于Doze模式,(2)Doze模式的行为与我们的期望不符。

谷歌已更新页面优化Doze和应用待机,但与您的发现不符。他们在了解Doze模式对您的应用程序意味着什么后台工作、闹钟和您的Android应用程序的流程图中提供了额外的信息。还请参见问题2225

恐怕这仍然无法解释您的结果。Doze模式很复杂,文档不足。

问:您的应用程序是否在白名单中?优化Doze和应用待机页面说:

在白名单中的应用程序可以在Doze和应用待机期间使用网络并保持部分唤醒锁定。

顺便说一下,命令

adb shell dumpsys deviceidle

显示当前状态(例如IDLE)以及其他信息,包括充电、运动和屏幕开/关状态,这些都是进入Dozing的先决条件,还有白名单。这对于调试非常有用。


这并没有回答我的问题。你基本上写了我在问题中写的相同步骤。 - Diffy
@Diffy确实,我已经放弃了那个假设,并用新的回答进行了重写。 - Jerry101
@Diffy 应用程序是否被加入白名单?这可能是原因。 - Jerry101
不,我的应用程序没有被列入白名单,@Jerry101。 - Diffy

0

我认为如果你有网络连接,即使在待机模式下,网络仍会显示为已连接,但是如果你尝试做除了 GCM 以外的任何事情,它都会抛出错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接