【问题标题】:Context.startForegroundService() ANR without actually calling itContext.startForegroundService() ANR 没有实际调用它
【发布时间】:2018-05-30 01:44:17
【问题描述】:

在将我的应用更新为目标 API 27(之前为 25)后,我遇到了许多来自用户的 ANR,我无法重现。它们似乎与 Oreo 后台执行限制有关,带有 ANR 消息

Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{73bc351 u0 com.xxx.xxxx/.player.PlayFileService}

但是我没有在我的代码中的任何地方调用Context.startForegroundService()。产生此 ANR 的原因有哪些,但不是直接调用此方法的结果?

【问题讨论】:

    标签: android android-service android-8.0-oreo android-anr-dialog foreground-service


    【解决方案1】:

    在我的情况下,即使我没有直接调用Context.startForegroundService(),它也会被调用,因为我的音乐应用程序会进入后台并且服务会被系统破坏。然后,当用户在几分钟后按下媒体按钮以恢复播放时,系统将重新启动该服务,因为该应用程序处于后台,因此该调用。我最终确实打电话给startForeground(),但这是在进行了一堆配置之后。我在服务的onCreate() 开头添加了对startForeground() 的呼叫,但通知为空白,我所有的ANR 都消失了。

    【讨论】:

      【解决方案2】:

      根据文档:

      在 Android 8.0 之前,创建前台服务的常用方法是 创建一个后台服务,然后将该服务推广到 前景。 Android 8.0 有一个并发症;系统 不允许后台应用创建后台服务。为了 为此,Android 8.0 引入了新方法 startForegroundService() 在前台启动新服务

      系统创建服务后,应用有 5 秒时间 调用服务的 startForeground() 方法来显示新服务的 用户可见的通知。 如果应用没有调用 startForeground() 时限内,系统停止服务并声明 应用 ANR

      您可以关注这个SO,它描述了使用通知通道正确启动前台服务的方法。

      【讨论】:

      • 我是用老方法做的。我只在应用程序处于前台时调用 startService(),并在 Activity 进入后台并在通道中发出通知时调用 startForeground()。我无法在我的应用中调用新的 startForegroundService()。
      • @SteveM 当您的应用在后台时,您无法使用context.startService() 启动服务。你需要使用startForegroundService()
      • 我没有在后台使用应用程序启动Service()。如果我这样做了,我会得到 IllegalStateException。
      • @SteveM 只是为了明确一点,当应用程序处于前台时,您正在启动服务,而当应用程序进入后台时,您只需将其设为前台?
      • 是的,我在 onPause 中调用 startforeground
      猜你喜欢
      • 2018-08-19
      • 2017-11-09
      • 2019-01-09
      • 2018-03-29
      • 2018-03-04
      • 1970-01-01
      • 2019-09-17
      • 1970-01-01
      相关资源
      最近更新 更多