GCM网络管理器丢失作业

7
我正在尝试使用GCM Network Manager将日志发送到我们的后端服务。我们每个小时运行一个闹钟,创建一个OneoffTask,在执行时将调用后端服务并发送日志消息。
这个方法确实可以执行,但是非常大量的任务都会丢失(远超过一半)。一开始,我认为这可能与我们的后端或网络有关,但是在添加了大量文件记录之后,发现这些任务的onRunTask从未被触发(但它们肯定已被计划)。为什么会出现这种情况?我是否误解了API,或者OneoffTasks不可靠?
以下是如何调度OneoffTask的方式:
GcmNetworkManager.getInstance(context).schedule(new OneoffTask.Builder()
    .setService(AvroLogService.class)
    .setExtras(bundle)

    // A mandatory tag which identifies the task
    // We add a unique hash to the tag to make sure that
    // tasks are logged and not thrown away as dupes.
    // See: https://dev59.com/8JLea4cB1Zd3GeqP3Yjy
    .setTag(java.util.UUID.randomUUID().toString())

    // Persist to disk, even across boots:
    .setPersisted(true)

    // Sets a time frame for the execution of this task in seconds.
    // This specifically means that the task can either be
    // executed right now, or at latest at a certain point:
    .setExecutionWindow(0, TWO_WEEKS_IN_SECONDS)
    .build());

再次强调,这只适用于部分消息,对于后续丢失的消息,上述代码绝对被执行(我已添加文件日志以进行验证),但是没有相应的onRunTask触发器来处理丢失的消息。

我已经验证:

  1. 根据网络管理器实现指南更新了清单(https://developers.google.com/cloud-messaging/network-manager
  2. AvroLogService(我的服务)扩展了GcmTaskService
  3. 它重写了onRunTask
  4. 应用程序具有RECEIVE_BOOT_COMPLETED权限。
  5. AvroLogService未覆盖onStartCommand。

我迷失了方向。有人能分享一下这方面的见解吗?


您可能需要查看此GitHub帖子,以获取有关使用GcmNetworkManager的更多见解和示例。如果您还没有这样做,该帖子中提到了需要在onRunTask()内提供任务执行逻辑,并且您必须跟踪您需要的特定任务状态,以便实现您想要的功能。 - Teyam
谢谢你的帮助,但是那篇文章并没有提供任何有关这个问题的相关见解。该文章讨论了将数据传递给任务,而我正在使用setExtras功能(当时写该文章时似乎不存在),但这与此问题无关。问题在于onRunTask内部的代码间歇性地未被执行。也就是说,它被执行了很多次,但也失去了许多排队的任务。就像很大一部分任务被简单地丢失了,从未到达onRunTask,即使它们已经成功排队。 - Mattias Petter Johansson
请在终端中输入以下命令:adb shell dumpsys activity service GcmService。当其他应用程序也使用GCM网络管理器时,它们可能会阻止您的请求。 - Mysterious_android
2个回答

0

我猜你的常量TWO_WEEKS_IN_SECONDS实际上指的是 2 周。在这种情况下,你的任务可以在从现在到 2 周内的任何时间点执行。因此,这个任务不需要每小时执行一次。 尝试设置执行窗口在一个小时甚至更短的范围内(.setExecutionWindow(0, HALF_AN_HOUR_IN_SECONDS)

请参考google api 文档


如果任务无法在那段时间内执行会发生什么? - Mattias Petter Johansson
根据我的经验,在大多数情况下,如果在时间窗口内条件不满足,任务将被推迟,但我找不到任何官方文档来证明这一点。 - Roman_D
@MattiasPetterJohansson,将HALF_AN_HOUR_IN_SECONDS设置有用吗?请确认。 - Mysterious_android
很久以前,我已经记不清了。说实话,我真的很高兴不再做更多的Android开发。 :) - Mattias Petter Johansson

0

如上所述,执行时间范围可能太大了。此外,我认为您想要定期执行事件,请尝试使用PeriodicTask.Builder而不是OneoffTask.Builder


是的,PeriodicTask可能是一个很好的替代方案,但请注意它在Doze期间可能无法执行。 - Roman_D

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