android O 對後臺服務的限制

現象


android o版本(8.0)及以上版本,當應用處於後臺時執行startService時,會拋出以下異常:java

Caused by: java.lang.IllegalStateException: Not allowed to start service ... app is in background uid UidRecord ...android

初步理解爲因爲app處於後臺時startServic不被容許app

緣由分析


從android O版本開始,google爲了控制資源使用增長了兩項後臺限制:源碼分析

  • 後臺服務優化

  • 廣播ui

其中對於後臺服務的限制,指的是若是應用處於後臺,則不容許直接使用startService。google

那什麼是後臺應用?後臺的對立面是前臺,google對於前臺的定義以下:設計

  • 具備可見的activity(無論該activity已啓動仍是已暫停)3d

  • 具備前臺服務日誌

  • 有關聯的前臺應用(如壁紙,通知偵聽器等)

具體可參考官方連接:

developer.android.com/about/versi…

解決方案


既然咱們使用了後臺服務,必然是一些無需用戶感知的場景,故考慮替換爲前臺服務的可能性不大;

從google對前臺應用的解釋入手,能夠經過製造前臺場景的方式使本身的應用處於前臺;

官方還說起了JobScheduler替代後臺服務的方案,能夠根據的業務場景選擇是否使用;

startService的方式也不須要徹底放棄。爲了適配8.0手機,須要先判斷應用是否在前臺再決定是否使用startService;

判斷應用是否在前臺的方式不少,主要原理有兩種:

  • 經過AM判斷應用前臺activity個數

  • 經過actvitiy生命週期回調計數(Activity回調、ActivityLifecycleCallbacks)判斷是否有前臺界面

實現的方式不少,自行google

設置targetSdk < 26也能夠實現該新特性規避。

源碼分析


startService大體流程以下:

ContextImpl#startServce ->

ContextImpl#startServceCommon ->

AMS#startService ->

ActiveServices#startServiceLocked ->

AMS#checkAllowBackgroundLocked

8.0.0

ContextImpl.java#startServiceCommon

image

紅框中爲日誌信息的來源

ActivityServices.java#startServiceLocked

image

另外一處Log信息的來源:app is in background

r.startRequested第一次初始化,默認爲false;fgRequired爲傳入的值false,故能夠進入後續邏輯;

經過AMS#getAppStartModeLocked獲取的allowed爲決定值,意思是是否容許後臺運行,返回值有多種類型(從代碼提交中能夠看出原先是boolean,如今是int)。

google 在一年前(2016~2017)針對後臺應用的判斷以及後臺執行限制作了大量的提交,從記錄中能夠看到:

image

image

以前提到經過設置targetSdk<26的方式就能夠,可是這僅僅是從8.0特性的代碼層面分析得知,這種方式並不能阻止7.x系統中對後臺服務的限制。

ActiveServices.java # startServiceLocked

image

7.1.1 AMS 是否容許後臺服務啓動所關心的主要仍是 當前進程的優先級 和 是否有後臺運行權限

image

8.0 AMS 中間的流程較7.x稍微複雜一些,大體流程以下:

AMS # getAppStartModeLocked ->

AMS # appServicesRestrictedInBackgroundLocked ->

AMS # appRestrictedInBackgroundLocked

image

這裏至關因而後臺服務特權的檢查,只要知足三者之一:

  • 有persistent權限

  • 後臺運行白名單

  • 電源優化白名單

就直接可使用後臺服務,前兩個均爲系統應用才能設置;

均不知足則繼續走後面的判斷流程,重點來了,8.0中優先判斷targetSdk是否在O版本及以上,是則直接返回不容許,否纔會判斷是否有後臺運行權限!

image

因此,若是須要有後臺運行的邏輯,8.0如下版本優先開啓後臺運行權限,8.0及以上版本優先開啓電源優化白名單

隨着Android版本的更新,早先年使用的保活黑科技逐漸都失效了,如今須要着重在產品層面設計,引導用戶開啓相關權限纔是迫在眉睫的需求。

總之,Google對後臺的限制愈來愈嚴格,不只限制了各類拉活行爲,也限制了搶佔後臺資源的行爲,各大app須要提早作好高版本適配。

相關文章
相關標籤/搜索