關於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已經放出,我認爲不會。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章