版權(quán)聲明:
本公眾號(hào)發(fā)布的所有文章,均屬于原創(chuàng),版權(quán)歸本公眾號(hào)所有。
允許有條件轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)附帶底部二維碼。
1、什么是Foreground Service
Foreground Service被稱為前臺(tái)服務(wù),一般用于提高Service的優(yōu)先級(jí),這樣在正常系統(tǒng)回收的時(shí)候,不會(huì)被系統(tǒng)殺死。
前臺(tái)服務(wù)通常用于那些,比較需要有穩(wěn)定性,并且持續(xù)在后臺(tái)運(yùn)行的操作。例如:音樂(lè)播放器、下載服務(wù)等。這樣在系統(tǒng)內(nèi)存較低而觸發(fā)Low Memory Killer的時(shí)候,不會(huì)被殺掉。為此,Google為了讓這樣的一個(gè)頑強(qiáng)的服務(wù)在后臺(tái)運(yùn)行,需要強(qiáng)制在通知欄設(shè)置一個(gè)可被顯示的通知。它被放到了“正在運(yùn)行(Ongoing)”標(biāo)題之下,意味著只有這個(gè)Service完成既定任務(wù),或者被從前臺(tái)刪除掉,這個(gè)通知才會(huì)被刪除。
2、如何使用前臺(tái)Service
前臺(tái)服務(wù)使用起來(lái)非常的簡(jiǎn)單,只需要兩個(gè)方法:

具體的功能,看上面的文檔已經(jīng)標(biāo)識(shí)清楚了。就不一一解釋了,簡(jiǎn)單來(lái)說(shuō),只需要在服務(wù)啟動(dòng)的時(shí)候,調(diào)用startForeground()方法,在其中傳入一個(gè)待顯示的Notification即可。停止前臺(tái)服務(wù),需要調(diào)用stopForeground()方法。
啟動(dòng)完成服務(wù)之后,在系統(tǒng)通知欄中,就可以看到被置為前臺(tái)服務(wù)的通知提示。

2、去掉前臺(tái)服務(wù)的Notification
馬上進(jìn)入主題了。
有時(shí)候某些功能,為了讓Service可以常駐內(nèi)存中,以避免在觸發(fā)Low Memory Killer的時(shí)候不被系統(tǒng)殺掉回收。一般就會(huì)想到前臺(tái)服務(wù)這個(gè)功能,將服務(wù)置換到前臺(tái)運(yùn)行。但是前臺(tái)服務(wù)又必須在通知欄中,常駐一條通知,無(wú)論怎么操作都不會(huì)消失。但是有時(shí)候確實(shí)會(huì)有一些需求,需要在后臺(tái)一直保持運(yùn)行,但是又想做到用戶無(wú)感知。那么就需要想辦法去掉這個(gè)在通知欄中顯示的Notification。
那么問(wèn)題來(lái)了,如何去掉前臺(tái)服務(wù)的Notification?
試過(guò)很多方法,現(xiàn)在行之有效的方法是:
- 需要兩個(gè)前臺(tái)服務(wù),共享同一個(gè)Notification ID。
- 一個(gè)服務(wù)啟動(dòng)完畢之后,馬上停止自己,會(huì)去掉通知欄的通知。
- 而之前已經(jīng)借助這個(gè)ID保持前臺(tái)的服務(wù),依然會(huì)處于前臺(tái)的狀態(tài)不變。
3、實(shí)施方案
先創(chuàng)建【B服務(wù)】。

然后修改我們真是需要運(yùn)行的【A服務(wù)】。

這樣運(yùn)行完成之后,查看通知欄,發(fā)現(xiàn)確實(shí)這個(gè)前臺(tái)服務(wù)的通知,被從通知欄中移除了。
4、驗(yàn)證方案
那么,既然這個(gè)服務(wù)已經(jīng)被運(yùn)行了,但是是否真的是前臺(tái)服務(wù)呢?接下來(lái)我們用dumpsys命令驗(yàn)證一下,看看當(dāng)前的服務(wù)是否和我們預(yù)期的一致。
首先需要進(jìn)入adb shell的環(huán)境,然后再執(zhí)行
$ dumpsys activity services | grep plokmju

注意看,isForeground標(biāo)識(shí)當(dāng)前服務(wù)是前臺(tái)服務(wù),而確實(shí)用于消除通知的BootService也已經(jīng)被正常停止了。
5、結(jié)語(yǔ)
雖然這樣的方式確實(shí)非常的方便可以將一個(gè)前臺(tái)的服務(wù),去掉通知欄通知,做到真的讓用戶無(wú)感知。但是作為一個(gè)有節(jié)操的程序員,使用這種方案一定要權(quán)衡一下,是否真的需要這樣一個(gè)服務(wù)在后臺(tái)運(yùn)行。當(dāng)然,這樣做為一個(gè)Bug的存在,據(jù)說(shuō)在Android 7.1的時(shí)候被修復(fù)了,但是鑒于現(xiàn)在設(shè)備版本的鋪量還沒(méi)有那么大,這種方式在低版本上依然適用。
