【发布时间】:2020-06-23 01:20:19
【问题描述】:
假设我们正在开发一个消息传递应用程序,我们希望将消息发送到给定的对话中,这些消息的顺序仅在该对话中很重要,如果应用程序被置于后台,我们希望保证消息将被发送。
WorkManager#beginUniqueWork 方法似乎很适合这种情况,其中uniqueWorkName 将是一些对话 id,ExistingWorkPolicy.APPEND 将用作工作策略以保持工作按计划进行。
到目前为止,在我的应用程序中,只要每个 Work 返回 Result.SUCCESS,那么任何未来计划的工作都会按预期执行。但是,如果一条特定消息未能以致命方式发送并且我返回 Result.FAILURE,那么所有未来使用相同对话 id 的工作似乎永远不会达到我对 Worker#doWork() 的实现。
在挖掘EnqueueRunnable 类的源代码之后,这似乎是一个非常慎重的选择。我真的不明白为什么会这样?奇怪的是,如果 uniqueWorkName 失败,该名称将在应用程序的剩余生命周期中变得不可用(这会在终止应用程序时持续存在)。
此外,我想知道是否有人对此有很好的解决方案,或者知道这是否会在 WorkManager 的未来版本中发生变化。到目前为止,我能想到的最好的事情是返回Result.SUCCESS,但在输出Data 中编码我自己的失败状态,这样任何工作的观察者都知道它失败了。然而,这有点尴尬,并且对于代码的未来维护者来说并不是很明显(并且在查看给定 Work 的日志时可能会有点混乱)。
也许我对独特作品的预期用途是完全错误的,并且有更好的解决方案。任何想法将不胜感激,谢谢!
【问题讨论】:
-
如果不更好地了解您要达到的目标,就很难回答。如您所见,返回Result.FAILURE 的效果是,任何依赖于此的工作也将被标记为失败并且不会运行。这个想法是一个 FAILURE 向 WorkManager 表明在这个链中不能做更多的事情。另一种看待它的方式是,这个返回值用于向 WorkManager 指示下一步要做什么(SUCCESS => continue, FAILURE => stop, RETRY => re-run the current worker)。
-
@pfmaggi 这对于在链入队之前映射出依赖关系的工作链来说都是非常有意义的,但这里我说的是 uniqueWork,特别是如果一个独特的工作失败,所有未来发布到同名的工作将永远不会被安排,即使在发布最新的 uniqueWork 时,当前没有工作正在执行。基本上一旦失败,那个特定的
uniqueWorkName在应用程序的剩余生命周期中将无法使用,这对我来说是出乎意料的。 -
@pfmaggi 感谢您的反馈,我想要实现的哪一部分不清楚?我试图在前 2 段中描述这一点,但如果您认为缺少某些内容,我会添加更多信息
-
重新阅读你的前两段,这很有意义。但是话又说回来,如果您无法发送链中的一条消息,您想做什么?只是发送其他人(缺少消息)或重试?就个人而言,我认为最好的选择是重试发送“失败”消息。您在哪些情况下返回失败?
-
一个特殊的例子是,如果我们尝试发送消息的时间过长,那么我们可能希望发送失败并将其报告给用户,然后他们可以决定我们是否应该重试(也许消息现在已过期)。正如我所提到的,现在我只是返回
Result.SUCCESS并将一些失败代码放入输出Data,但现在我真的不想调用Result.FAILURE,否则对话变得无法使用,这看起来很奇怪我!
标签: android android-jetpack android-workmanager