谷歌在安卓12以及以后的系統(tǒng),對應(yīng)用啟動服務(wù)進(jìn)行了更嚴(yán)格的限制,如果需要應(yīng)用在后臺停留的時候缰犁,仍然能夠執(zhí)行后臺代碼邏輯,這個時候需要通過前臺服務(wù)的機制怖糊,前臺服務(wù)和一般的服務(wù)API有兩處不同帅容,1是啟動服務(wù)的時候需要使用startForegroundService啟動服務(wù),其次是在前臺服務(wù)啟動之后必須要在5s內(nèi)調(diào)用startForeground,否則會導(dǎo)致ANR或者崩潰
前臺服務(wù)有什么限制伍伤?
- 安卓12之后并徘,在后臺啟動前臺服務(wù)可能會導(dǎo)致應(yīng)用崩潰,除非滿足某些豁免條件
- 服務(wù)的startForeground方法可能會崩潰扰魂,需要try catch
- 不要給startForeground傳入一個無效的通知id,可能會導(dǎo)致前臺服務(wù)拉起失敗
- 調(diào)用了stopForeground之后ams不再認(rèn)為當(dāng)前服務(wù)是前臺服務(wù)麦乞,這個時候我們可以通過startForeground重新讓當(dāng)前服務(wù)變成前臺服務(wù)(前提是服務(wù)沒有被殺死&并且如果在后臺的時候滿足相關(guān)豁免條件),否則startForeground的調(diào)用會發(fā)生崩潰
什么時候會導(dǎo)致ANR?
用戶startForegroundService蕴茴,5s內(nèi)沒有調(diào)用startForeground,并且沒有殺死服務(wù),那么5s后會看到anr
什么時候會崩潰
用戶startForegroundService姐直,在startForeground還沒有調(diào)用前倦淀,調(diào)用了stopService或者stopSelf殺死了服務(wù),這個時候多半會看到ForegroundServiceDidNotStartInTimeException這個異常
通常來說,當(dāng)我們?nèi)シ治鼍€上的ANR的情況的時候声畏,我們會傾向于主線程發(fā)生了耗時操作撞叽,前臺服務(wù)導(dǎo)致的ANR這一點可能會被忽略,因為前臺服務(wù)導(dǎo)致的ANR,日志上報的情況往往展示當(dāng)前主線程是空閑的!! 用傳統(tǒng)思路去解決anr可能無法切中要害
如何規(guī)避前臺服務(wù)相關(guān)的ANR和崩潰
方法一
在服務(wù)onCreate 以及onStartCommand最開始的調(diào)用中就調(diào)用startForeground
方法二(推薦)
前臺服務(wù)僅用作辈辶洌活愿棋,只在onCreate中調(diào)用一次startForeground,后續(xù)所有對服務(wù)的使用通過服務(wù)的Binder機制直接使用接口調(diào)用,如果服務(wù)和應(yīng)用程序在同一個進(jìn)程中均牢,也可以通過服務(wù)在onCreate的時候往一個全局的單例注冊一個接口糠雨,服務(wù)銷毀的時候接注冊該接口,也就是自己”模擬下“服務(wù)Bind的過程