一个没有Notification的前台服务
版权声明:
本公众号发布的所有文章,均属于原创,版权归本公众号所有。
允许有条件转载,转载请附带底部二维码。
1、什么是Foreground Service
Foreground Service被称为前台服务,一般用于提高Service的优先级,这样在正常系统回收的时候,不会被系统杀死。
前台服务通常用于那些,比较需要有稳定性,并且持续在后台运行的操作。例如:音乐播放器、下载服务等。这样在系统内存较低而触发Low Memory Killer的时候,不会被杀掉。为此,Google为了让这样的一个顽强的服务在后台运行,需要强制在通知栏设置一个可被显示的通知。它被放到了“正在运行(Ongoing)”标题之下,意味着只有这个Service完成既定任务,或者被从前台删除掉,这个通知才会被删除。
2、如何使用前台Service
前台服务使用起来非常的简单,只需要两个方法:
startForeground_method.png具体的功能,看上面的文档已经标识清楚了。就不一一解释了,简单来说,只需要在服务启动的时候,调用startForeground()方法,在其中传入一个待显示的Notification即可。停止前台服务,需要调用stopForeground()方法。
启动完成服务之后,在系统通知栏中,就可以看到被置为前台服务的通知提示。
notification.png2、去掉前台服务的Notification
马上进入主题了。
有时候某些功能,为了让Service可以常驻内存中,以避免在触发Low Memory Killer的时候不被系统杀掉回收。一般就会想到前台服务这个功能,将服务置换到前台运行。但是前台服务又必须在通知栏中,常驻一条通知,无论怎么操作都不会消失。但是有时候确实会有一些需求,需要在后台一直保持运行,但是又想做到用户无感知。那么就需要想办法去掉这个在通知栏中显示的Notification。
那么问题来了,如何去掉前台服务的Notification?
试过很多方法,现在行之有效的方法是:
- 需要两个前台服务,共享同一个Notification ID。
- 一个服务启动完毕之后,马上停止自己,会去掉通知栏的通知。
- 而之前已经借助这个ID保持前台的服务,依然会处于前台的状态不变。
3、实施方案
先创建【B服务】。
Notice_bootService.png然后修改我们真是需要运行的【A服务】。
notice_real_service.png这样运行完成之后,查看通知栏,发现确实这个前台服务的通知,被从通知栏中移除了。
4、验证方案
那么,既然这个服务已经被运行了,但是是否真的是前台服务呢?接下来我们用dumpsys命令验证一下,看看当前的服务是否和我们预期的一致。
首先需要进入adb shell的环境,然后再执行
$ dumpsys activity services | grep plokmju
isForeground.png注意看,isForeground标识当前服务是前台服务,而确实用于消除通知的BootService也已经被正常停止了。
5、结语
虽然这样的方式确实非常的方便可以将一个前台的服务,去掉通知栏通知,做到真的让用户无感知。但是作为一个有节操的程序员,使用这种方案一定要权衡一下,是否真的需要这样一个服务在后台运行。当然,这样做为一个Bug的存在,据说在Android 7.1的时候被修复了,但是鉴于现在设备版本的铺量还没有那么大,这种方式在低版本上依然适用。
公众号二维码.jpg