我正在尝试使用GCM网络管理器将日志发送到后端服务。我们大约每小时运行一次警报,创建一个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: http://stackoverflow.com/q/34528960/304262
.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。
我已经证实:
- 根据《Network Manager实施指南》更新清单(https://developers.google.com/cloud-messaging/network-manager)
- AvroLogService(我的服务)扩展GcmTaskService
- 它覆盖onRunTask
- 该应用程序具有RECEIVE_BOOT_COMPLETED权限
- AvroLogService不会覆盖onStartCommand
我迷路了。有人能分享这方面的见解吗?
如上所述,执行时间范围可能太大。此外,我认为您希望定期执行事件,请尝试使用PeriodicTask.Builder而不是OneoffTask.Builder
我猜您的常数TWO_WEEKS_IN_SECONDS
实际上意味着2周。在这种情况下,您的任务可以在从现在到2周的任何时间点执行。因此,这个任务不必每小时执行一次。尝试将执行窗口设置在一小时甚至更短的范围内(.setExecutionWindow(0, HALF_AN_HOUR_IN_SECONDS)
)
请参阅谷歌api文档