android-WorkManager:为什么使用“ APPEND” ExistingWork策略进行的唯一工作失败,为什么不允许使用相同名称进行更多工作?
作者:互联网
假设我们正在开发一个消息传递应用程序,我们希望将消息发送到给定的对话中,这些消息的顺序仅在该对话中很重要,并且如果该应用程序置于后台,我们希望保证消息将被发送.
为此,WorkManager#beginUniqueWork方法似乎是理想的方法,其中uniqueWorkName将是一些对话ID,并且ExistingWorkPolicy.APPEND将用作工作策略,以使工作按计划的顺序进行.
到目前为止,在我的应用程序中,只要每一项工作都返回Result.SUCCESS,那么将来任何计划的工作都将按预期执行.但是,如果一条特定的消息无法以致命的方式发送,并且我返回Result.FAILURE,则以后所有具有相同对话ID的工作都永远不会到达我的Worker#doWork()实现.
在深入研究EnqueueRunnable类的源代码之后,这似乎是一个非常刻意的选择.我真正无法理解的是为什么呢?奇怪的是,如果uniqueWorkName失败,则该名称在应用程序的整个生命周期中都变得不可用(这在终止该应用程序之前一直存在).
此外,我想知道是否有人对此有一个好的解决方案,或者想知道这在WorkManager的未来版本中是否会改变.到目前为止,我能想到的最好的办法是返回Result.SUCCESS,但在输出数据中编码我自己的失败状态,以便工作的任何观察者都知道它已失败.但是,这有点尴尬,对于将来的代码维护者来说不是很明显(并且在查看给定工作的日志时可能会有些混乱).
也许我原本打算使用独特作品的做法是完全错误的,并且有更好的解决方案.任何想法将不胜感激,谢谢!
解决方法:
因此,我在this google issue tracker report中找到了自己的问题的答案.
基本上,使用APPEND策略的独特工作会创建一个WorkContinuation,在其中将每个新项目链接在一起,就好像我们要使用WorkContinuation#then方法一样.失败或取消链后,将取消所有下游工作,因此这是预期的行为.
凭单建议了两种方法:
If you really want APPEND’s behavior, then another thing you could do is to check for WorkStatuses of the WorkRequests, and if (all of them happened to be cancelled) use REPLACE instead of APPEND. Bear in mind, this is inherently racy, because your WorkRequests might not have cancelled yet. So make sure you have some synchronization primitives around your use of WorkManager’s APIs.
和
The simplest way to do this is to not actually return Result.FAILED; if you always return SUCCEEDED and return the actual pass/fail bit (if needed) in the output data, you can make sure the chain always keeps running.
这就是我已经在做的.希望这对其他人有帮助.
标签:android-jetpack,android-workmanager,android 来源: https://codeday.me/bug/20191024/1924431.html