今天早上特地來公司早了一個小時,趕緊把昨天沒說完的關於JobInfo中的幾個約束條件結束掉,儘管時間緊張閱讀量也不怎麼可觀,但是還是不能斷是吧,萬一真的有哪位同學就等著講完約束條件呢?況且才更新了幾天安卓技術類文章自己都養成習慣了。
好吧,開場白就講到這裡,如果你是一位安卓開發者正好手頭上有兩三分鐘的空閒時間那麼就可以繼續看下去了。
在上一章節《安卓程式設計師:低電量如何做優化?這兩個方法或許可以幫到你》我們講到了與低電量優化的兩個約束,那麼今天來講講設備空閒約束。
那麼什麼是設備空閒約束呢?其實「空閒」這兩個字聽起來就給人一種模稜兩可的感覺,按照通常的理解以及我們看過了Android 6.0 (API level 23)關於device idle和doze介紹後,大部分開發者可能覺得設備長時間沒操作屏幕自然進入鎖屏狀態時就可以稱為空閒了,在這種狀態下網絡請求或者一些後臺可能會受到限制。
但是今天我們要說的空閒與上面提到的doze可能有點不一樣,JobInfo條件約束中的空閒只限定用戶在某一段時間有沒有與設備交互,至於這個時間是多少是由系統控制。
講了這麼多,還沒有說到具體的方法是什麼,這個方法就是requiresDeviceIdle,參數就一個布爾型,默認值false表示無論設備是否空閒都會執行具體的任務。
那麼什麼情況下會傳true呢?按照官網的解釋,系統處於空閒狀態時是一個處理比較耗系統資源任務的最好時機,比如說大量的IO處理或者繁雜的計算操作。Android認為如果應用中有這類操作並且這類操作是可以在後臺執行的話那麼requiresDeviceIdle(true)就是一個比較合理的方式了。
最後來說說這個方法的測試,在JobInfo中就數這個方法最難測試。從官網的說明來看,添加這個約束後只要在一段時間內用戶沒有與設備發生交互那麼條件就會滿足,意味著任務能夠被執行。然而,經測試後(pixe & android p)並沒有達到期望,並且國外安卓開發者也反映等了幾個小時也沒有看到任務執行。
甚至有安卓開發者通過shell命令讓設備進入doze模式,發現仍然沒有起作用。其實在Android 6.0中引入doze概念時也對設備進入doze狀態時的限制活動作了說明,最後一條明確寫到了doze狀態不允許JobScheduler運行,所以通過這一點來測試requiresDeviceIdle方法也走不通。
不過分析JobSchedulerService源碼可知,處理空閒約束的類是IdleController,其中有一個叫做IdlenessTracker的內部類,該類繼承BroadcastReceiver,負責監聽以下幾個與設備空閒相關事件。
當事件狀態發生變化後執行下面這段邏輯,滿足if判斷後才開始把任務交給AlarmManager執行。令人遺憾的是,仔細分析源碼筆者仍然未能觸發設備空閒狀態。
由於時間有限未能對這塊做仔細地研究,後面有空時會加以補充,如果哪位同僚知曉請予以告知。