android 8.0 foregroud-service的坑
ForegroudService
都知道8.0以后,不可以在后台调用startService()来启动一个服务,要想通过startService启动,必须activity在前台时才能使用。当然onResume和onPause状态下的activity都可以。但是,也有一种情况是例外。
https://developer.android.com/about/versions/oreo/background#services
这里在官方文档也有讲,就是: 进入后台时,在一个持续数分钟的时间窗内,应用仍可以创建和使用 Service。 也就是,当你的activity刚进入后台时,是可以调用startService的。
如果不使用startService,就得使用startForegroundService,但是需要绑定一个通知,可以在调用时传入通知id,也可以在调用后,通过startForeground来绑定。
然而,除了以上,还是有一些疏忽了的,需要注意的地方。
使用了startForegroudService还是有错
做了8.0兼容后,已经把所有的startService都改成了startForegroundService,但是后台还是得到了很多的错误,特别是在android 8.0 和8.1的机子上。
android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
经过排查,测试,发现还有一些需要注意的点,这里大概列一下。
可以不调用notify方法
首先,要想启动一个前台服务,必须使用startForegroundService,只要调用了startForegroundService,必须调用startForeground为其设置一个notification。
注意:这里的notification可以不调用notify方法,但是,在调用startForeground后,会自动调用这个notify方法将notification展示出来。
stopSelf前要startForeground
google文档显示,如果在5s内未调用startForeground,则系统将停止此Service并声明此应用为ANR。那么,5s内如果stopSelf()呢??亲测,这样也不行,按常理分析,如果直接调用stopSelf可行,是有违ForegroudService的设计初衷的。所以,在stopSelf前,如果想一个startForegroundService调用后直接关闭,也是需要调用startForeground()的。
stopForeground不要乱用
stopForeground是将一个service从前台改为后台的,如果你中途调用了stopForeground,再次调用startForegroundService时,一但没有走到startForeground,(比如是在onCreate方法中,就不会走到)还是会报出Context.startForegroundService() did not then call Service.startForeground()的异常,所以,看清楚再使用它。