关于Android Doze, App Standby, 和音频流的二三事

Android M中引入的两个重要的功能是Doze和Appstandby,目的是延长设备的电池寿命。

根据文档,实现前台服务的应用程序可以被App Standby豁免,但是没有关于Doze的类似说法。

M发布几个月后,很快就推出了大量设备,我们开始通过我们的客户支持获得一些“怪异”的抱怨:

我有三星Galaxy s6,刚刚更新到android 6.0.1。
我几乎每天都使用Spreaker收听我最喜欢的播客,直到现在还没有问题。
自从三天前Android更新后,app随机停止播放。

而且根据一些用户的说法,这也发生在他们口袋里的手机上(不是静止的)这就非常奇怪了。 

所以我再次开始使用Doze和App Standby进行实验,多次阅读文档,使用我们拥有的可以运行M的所有设备进行手动测试,我没有发现任何意外情况。显然强制设备进入Doze导致了他们报告的问题,同样适用于App Standby但是:

  • 由于有前台服务,我们的应用程序应该被App Standby豁免
  • 这些手机不是静止的,所以Doze不应该启动

仍然很奇怪。

这持续了几个月,直到几个星期前,当我决定对这些东西进行另一轮测试时,看看我是否能够找到新的东西。直到我偶然发现了这个Google+帖子,我开始阅读评论,直到我发现这个评论:

Apps that have been running foreground services (with the associated notification) are not restricted by doze. This covers a large number of these kinds of use cases.

WTF?我不知道这一点,它不在文档中,而且我们所做的所有手动测试都证明了完全相反!当我们的应用播放音频时,我关闭了屏幕,运行命令强制Doze:

$ adb shell dumpsys battery unplug 
$ adb shell dumpsys deviceidle step

并且应用程序立即开始报告网络问题,这意味着Doze起作用了,让我们继续阅读那篇文章的评论:

  • 该应用程序是从网络流式传输音频,您关闭屏幕并强制Doze =网络访问中断,应用程序停止流式传输
  • 该应用程序是从网络流式传输音频,您通过按HOME按钮把活动送入后台,然后关闭屏幕并强制Doze =网络访问仍然有效,应用程序继续流式传输

幸运的是,dumpsys工具可以提供一些额外的信息。让我们看看它的行为。

手机处于活动状态时:

$ adb shell dumpsys power | grep spreaker_player
PARTIAL_WAKE_LOCK 'spreaker_player' (uid=10309, pid=31020, ws=null) (elapsedTime=4524)

当关闭屏幕进入Doze之前,我们的Activity处于前台

$ adb shell dumpsys power | grep spreaker_player
PARTIAL_WAKE_LOCK'spreaker_player'DISABLED(uid = 10309,pid = 31020,ws = null)(elapsedTime = 20218)

当关闭屏幕进入Doze之前,我们的Activity处于后台

$ adb shell dumpsys power | grep spreaker_player
PARTIAL_WAKE_LOCK'spreaker_player'(uid = 10309,pid = 31020,ws = null)(elapsedTime = 64626)

通过最后一个实验我们得出的结论:

  • 如果应用程序实现前台服务,则App Standby和Doze都可以豁免
  • 由于6.x版本中存在BUG,如果您的应用活动在手机屏幕关闭时位于前台,则会使上述豁免条件无效
  • 此错误已在Nougat中修复。目前尚不清楚该修复程序是否会被移植到6.x分支,但此时Nougat已经放出,我认为不会。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章