【问题标题】:Having an Android service as both background and foreground service将 Android 服务作为后台和前台服务
【发布时间】:2020-06-05 17:28:04
【问题描述】:

我读到我应该打电话给

startForegroundService(intent)

如果我想正确启动可以作为前台服务运行的服务。但是,如果我希望它在不作为前台服务但以后可能成为前台服务的情况下启动,我应该怎么想?关于我们现在如何拥有它的一些信息:

我们有一个应用程序,它使用一项服务来完成许多任务。当用户在前台与应用程序交互时,它会执行所有这些任务,但取决于用户是否启用了某个功能,我们希望继续在后台执行这些任务。因此,当应用程序启动时(显然是在前台),我们使用

启动服务
startService(intent);

当应用程序转换到后台时,我们会检查该功能是否已启用,如果已启用,则运行 startForeground(id, notificiation);,这会有效地将不可移除的通知添加到操作系统中,并且服务会继续运行。当应用程序回到前台时,我们调用stopForeground(true)。如果未启用该功能,该服务将永远不会设置为前台服务,我们也不会尝试在后台执行这些任务。

所以我的问题是:这足以获得“完整的前台服务性能”吗?还是因为不打电话给startForegroundService(intent)而失去了一些东西?我的印象是,我们确实有一个完全正常工作的前台服务,但是当我读到 foreground services must be started using startForegroundService(intent) 我们没有做的声明时,我感到很困惑。如果我们真的需要使用startForegroundService(intent),我能想到的唯一解决方案是首先启动一个普通的服务实例,当应用程序进入后台时,我们使用startForegroundService(intent)启动一个新实例.但是我们需要这样做还是在使用startService(intent) 启动的服务上运行startForegund(id, notification) 足以实现前台服务?

注意: 我发现的一个区别是,如果应用程序本身在后台启动服务时,我需要 startForegroundService(intent) 用于 API >= 26。在我们的例子中,我们总是在以下时间启动服务该应用程序在前台。但是,我确实记得在某些情况下,当我们尝试使用 startService(intent) 启动服务时,我看到了抛出异常,不知何故,应用程序(非常罕见)仍然认为它在后台(也许当应用程序出现时来自操作系统的某些东西已启动)。因此,如果我发现这种情况发生时,我可以运行startForegroundService(intent) 来启动服务。但是当应用程序回到前台时,是否可以在该服务上运行stopForeground(true)?或者,自从我们以这种方式启动它之后,它就注定永远是前台服务吗?

【问题讨论】:

  • 我想你的答案是here。他们在 Android O 中添加了很多限制。运行长寿服务的唯一方法是在前台启动,否则,操作系统会杀死它们或抛出异常
  • 是的,但是当应用程序处于前台时,我们使用startService(intent) 启动后台服务,这仍然是允许的。然后,当应用程序进入后台时,我们使用startForeground(id, notification) 将其设置为前台。所以这并不能真正回答任何问题。如果应用程序在前台并且我运行startService(intent) 后跟startForeground(id, notification),这与运行startForegroundService(intent) 后跟startForeground(id, notification) 会有任何不同吗?

标签: android service foreground


【解决方案1】:

似乎您不必致电startForegroundServicestartService 就足够了:

如果您的服务已启动(通过 Context#startService(Intent) 运行),然后也使该服务在前台运行,在此状态下向用户提供持续通知以显示.默认情况下,启动的服务是后台的,这意味着它们的进程不会被给予前台 CPU 调度(除非该进程中的其他东西是前台),并且如果系统需要杀死它们以回收更多内存(例如显示大页面在网络浏览器中),它们可以被杀死而不会造成太大伤害。如果终止您的服务会对用户造成干扰,例如您的服务正在执行背景音乐播放,那么您可以使用 startForeground(int, Notification),这样用户会注意到他们的音乐是否停止播放。

来自Documentation

【讨论】:

    【解决方案2】:

    我多次阅读您的问题,我认为(希望)您的问题的答案是:

    根据Android 8.0 Background Execution Limits官方文档:

    Android 8.0 引入了新方法 startForegroundService() 在前台启动新服务。系统创建后 服务,应用程序有五秒钟的时间调用服务的 startForeground() 方法显示新服务的用户可见 通知。如果应用程序没有在 时限,系统停止服务并声明应用为 ANR。

    因此,请确保您已通过在服务的 onCreate() 方法中调用 startForeground (int id, Notification notification) 开始持续通知。

    注意:以 API Build.VERSION_CODES.P 或更高版本为目标的应用必须请求 Manifest.permission.FOREGROUND_SERVICE 权限才能使用此 API。

    Maciej Witowski 发布了一篇很棒的媒体文章,可以帮助您了解真正的新服务 API 是如何工作的: https://proandroiddev.com/pitfalls-of-a-foreground-service-lifecycle-59f014c6a125

    【讨论】:

    • 感谢您的回复,但如果我改写的话。从 Android 8 及更高版本开始,我们必须使用startForegroundService(),然后足够快地调用startForeground(),如果我们想当应用在后台时启动前台服务。但是,如果应用程序本身在前台,我们仍然可以使用startService() 后跟startForeground() 来启动前台服务。就我而言,我从应用程序处于前台时开始。然后,我这样做有什么不同吗?
    • 我读过的一些文章指定“你不能再使用 startService()”但是文档只是声明 Unlike the ordinary startService(android.content.Intent), this method can be used at any time, regardless of whether the app hosting the service is in a foreground state.
    猜你喜欢
    • 2022-01-19
    • 2023-03-28
    • 1970-01-01
    • 2011-04-02
    • 2015-08-17
    • 2018-04-18
    • 2011-09-15
    • 2020-01-19
    • 1970-01-01
    相关资源
    最近更新 更多