使用Context.startForegroundService(Intent)与使用Context.startService(Intent)相比,是否有使用前台服务的好处?

22
我在文档中读到,Context.startForegroundService()隐含地承诺启动的服务将调用startForeground()。然而,由于Android O有关后台和前台服务的更改即将推出,与使用旧的startService()方法相比,它是否还有其他性能改进,或者只是向前的最佳实践?
2个回答

33

这不涉及性能改进、优势或最佳实践。

从API 26开始,系统不再允许后台应用程序创建后台服务。

因此,如果您的应用程序在后台运行(如果在前台也可以这样做),则必须使用Context.startForegroundService(Intent)而非以前的startService(Intent)。服务必须在启动后的前5秒内调用startForeground(int, Notification),否则系统将停止该服务。

还应提到的是,目前在Android Oreo上使用后台应用程序以旧方式启动服务startService(Intent)仍然有效,但这很快会得到修复。

因此,从API 26开始,当您想要启动前台服务时,应使用新的Context.startForegroundService(Intent)方法而非startService(Intent)


1
有信息表明,使用startService(Intent)从后台应用程序启动服务的旧方法仍然有效。是否有来源? - Eugen Pechanec
这是否意味着我需要检查API是否大于等于26,如果是,则调用startForegroundService(),否则调用startService() - scarface
1
@scarface 是的,你必须检查它,否则在后台应用程序尝试调用startService()方法时会抛出异常。但我相信如果你使用标准的Android compat库,就可以避免手动编写该检查的代码。 - Alexander Abakumov
2
问题在于这5秒钟是非常短的时间。如果系统很忙,一个应该调用startForeground的Service对象可能会超过5秒钟没有被调用,并且偶尔(不总是)会导致应用程序崩溃。这是Google方面非常糟糕的设计,而且目前还不清楚如何解决。有什么想法吗? - Oleg Gryb
这里有一个更广泛的讨论:https://dev59.com/AVcP5IYBdhLWcg3wa5bQ,人们在那里开了一些错误,但谷歌没有采取措施解决。虽然有很多答案,但没有一个真正解决了这个问题。我在我的应用程序中也遇到了这个问题,并且每个月会崩溃一次。在这里发布堆栈跟踪不会有帮助。 - Oleg Gryb
显示剩余3条评论

4
如我在这里所解释的那样,startForegroundService 存在一个严重问题,将不可避免地导致偶发的 ANR (应用程序无响应)。由于此问题无法在应用程序级别上修复,因此不应使用 startForegroundService。我改用JobScheduler 和 JobService模型来实现相同的功能。

后一种模型目前工作良好,并且我再也没有在 Play Store 中看到应用程序崩溃。虽然新模型相当不同,但我花了两天时间基于 startForegroundService 重构现有代码,但它绝对是值得的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接