【问题标题】:Android Oreo killing background services and clears pending alarms, scheduled jobs after entering doze modeAndroid Oreo 杀死后台服务并清除挂起的警报,进入打盹模式后的预定作业
【发布时间】:2018-05-24 08:16:43
【问题描述】:

我的应用程序有一个后台 service 运行,它可以让用户获得最新的 location 并每五分钟将其更新到服务器。为了连续运行这个location 更新过程,我使用警报管理器从service 本身设置它的下一个执行时间。但是,当我在运行Android 8.1Nokia 6 中安装该应用程序时,它会工作一段时间,如果我让手机闲置一段时间,我的service 将被应用程序的下一个警报杀死,同时也被清除系统alarm manager。我的猜测是空闲时间使手机输入doze mode。但是,我不明白为什么警报管理器被清除了。据我了解,doze mode 应该定期打开维护窗口以执行任何待处理的任务。

为了缓解这个问题,我尝试在AlarmManager 之上应用JobScheduler service,它每15 分钟运行一次。这个jobscheduler 的目的是重新启动其中包含alarmmanagerservice,因此即使它被杀死并且警报被清除,jobscheduler 也会重新启动service

在我测试了这个补丁并将其保留一段时间以进入 idle mode 之后,它导致同时获得 JobScheduler ServiceService,其中的警报被预定的作业和警报杀死从系统中清除。

Android 文档中说我们可以使用JobScheduler 来缓解其后台执行限制。为了测试这一点,我在测试应用程序时强行杀死了两个services,但是已经安排好的作业没有被清除,它使带有警报的service 再次成功运行。我不明白这种行为的原因,尽管 Evernote 的家伙在这里给出了一个可能与这种情况相匹配的解释Android Job by Evernote

对这种异常行为有什么想法吗?

测试环境详情

  • 设备:Nokia 6 (TA-1021)
  • 操作系统:Android 8.1.0

【问题讨论】:

  • 你运行的是前台服务还是后台服务?您是否在服务的 onDestory() 中取消注册 AlarmManager?
  • @Sagar 我尝试在后台和前台运行。是的,我正在从 Job Scheduler 服务中注销警报。仅当它已经设置时。运行作业调度程序的目的是清理警报管理器并每 15 分钟重置一次警报
  • @k9yosh 你有没有找到任何解决方案或解决方法来让它在 Android Oreo 和 Oreo+ 设备上工作。我也收到了。
  • @QadirHussain 不,我没有。将您的代码移植到基于 FCM 的通知系统是最佳选择。它完美无瑕。
  • @k9yosh 感谢您的回复。你能告诉这个吗?收到推送通知时,我可以注册一个广播接收器(带有操作 ACTION_SCREEN_ON)吗?

标签: android alarmmanager android-jobscheduler


【解决方案1】:

由于行为发生变化,您将无法在 Oreo 中长时间运行后台服务,现在 Oreo 优化系统内存、电池等,它会杀死后台服务,为了解决您的问题,您应该使用前台服务。

查看后台执行限制https://developer.android.com/about/versions/oreo/android-8.0-changes

我的一个建议,如果你可以使用 FCM 那就去吧,因为微信、Facebook 等应用程序使用它来传递通知,它们不会遇到任何问题......

希望这有助于理解这个问题......

【讨论】:

  • 我尝试过使用前台,但它仍然被杀死了。我没有尝试 FCM,因为有一些限制。但这似乎是唯一可以尝试的选择。
  • @k9yosh 查看此链接,专门针对您的任务:developer.android.com/about/versions/oreo/…
  • 即使谷歌照片应用程序被杀,一旦我点击相机,它也会上传照片。这是如何做到的。任何想法。
  • @Durgaprasad 当你点击相机时,它会向谷歌照片发送意图,然后被它捕获,因此它开始工作......如果你通过正确的意图和用意图过滤器捕捉它。
  • 这太荒谬了,您需要一个 FCM 服务器来确保应用程序警报可靠地工作!这是一个不必要的矫枉过正......为什么Android让它的开发人员的生活如此悲惨?!我知道有坏玩家,但你仍然不能随意杀死警报。
【解决方案2】:

在 Doze more 中,警报不会被重置,而是推迟到以后的时间。这里有两种主流选择:

  1. 使用setAndAllowWhileIdle()setExactAndAllowWhileIdle()。但是,这些也可以以1 time per 9 minutes 的最大频率触发。因此,您必须降低在应用中获取位置的频率。

  2. 使用foreground service 来显示前台通知。每个人都这样做(优步、谷歌地图等应用程序)。这样,您的服务就不会被终止,并且会被视为您打开了一个应用程序。

【讨论】:

  • 我已经使用了这两个选项,但是仍然被杀死了。在打瞌睡模式下一段时间后,甚至前台服务也会被杀死
【解决方案3】:

我目前面临同样的问题,并且像您一样做同样的工作。也就是说,将 Jobscheduler 设置为定期作业,以每 15 分钟启动一次我的前台服务,以防它因任何原因(如被杀死的任务)而被杀死。这就像奥利奥前版本的魅力。

对于 Oreo,我目前知道的唯一解决方案是允许应用在设置中自动启动。在已安装的应用程序下。然后它应该再次像之前的奥利奥一样工作。 我听说但尚未测试的是在 Job Scheduler 中设置 setPersisted(true) 选项。 让我知道这是否有帮助

【讨论】:

  • 是的,您的第一个解决方法适用于 pre oreo 版本。我尝试了同样的事情,但反过来。在除奥利奥以外的其他版本中工作正常。我将尝试您的第二种解决方法并回复您。对这种行为有什么解释吗?
  • 我试过 setPersisted(true),但它在带有 Miui 的小米 Mi Mix2 上对我不起作用。但由于他们有自己的方式在后台处理应用程序,这并不一定意味着什么。到目前为止,我唯一的解释是 Oreo 不允许启动既不属于前台也不属于后台的应用程序,除非您通过自动启动设置专门允许它。不幸的是,我目前还没有意识到解决方法。
  • 对我来说同样的问题是否有任何解决方法可以管理打盹模式??
【解决方案4】:

我假设当前打盹模式不允许后台服务,所以你需要找到一种打盹模式不会影响你的应用程序的方法。要解决你的问题,你应该使用前台服务。或进行一些电池设置。无论如何,我更好的选择是你应该选择Firebase Cloud Messaging

【讨论】:

    猜你喜欢
    • 2019-04-25
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 2016-01-06
    相关资源
    最近更新 更多