WorkManager监听器立即被调用

7

我需要在WorkManager(android.arch.work:work-runtime-ktx:1.0.0-alpha11)完成工作后回调。但是,我添加的监听器会在工作被安排后立即调用。

这是我的做法:

val work = OneTimeWorkRequestBuilder<UploadWorker>()
                .setConstraints(constraints)
                .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)
                .setInputData(inputData)
                .build()
workManager.beginUniqueWork(INSURANCE_UPLOAD_WORKER, ExistingWorkPolicy.REPLACE, work)
                .enqueue().result.toWorkResult()

上传工作器(UploadWorker)类只有在完成整个上传序列后才会返回 Success。

以下是扩展函数的代码:

private val executor = Executor { command -> command?.run() }

class WorkResult(private val future: ListenableFuture<*>) {

    fun addListener(listener: () -> Unit) {
        future.addListener(Runnable {
            debugLog("work result listener runnable called")
            listener()
        }, executor)
    }

}

internal fun ListenableFuture<*>.toWorkResult(): WorkResult {
    return WorkResult(this)
}

当我给WorkResult添加监听器时,它们会立即调用,而不需要等待实际工作完成。对此有何想法?

你解决了这个问题吗? - pavol.franek
仅返回翻译文本:只返回它的第一部分 - Євген Гарастович
2个回答

2

在找到一个合适的解决方案(没有垃圾回收错误等)之前,一种基本的方法是创建另一个WorkRequest并将其链接为最后一个工作请求来处理状态。

当然,您必须单独处理错误状态(并始终为每个WorkRequest返回Result.success),以允许通过链传播。

这绝不是可持续的方法,而只是在必要时的快速修复。


0
问题不会出现,如果您像这样使用liveData获取结果,而不是使用ListenableFuture。
WorkManager.getInstance()
.getWorkInfoByIdLiveData(cloudSyncOneTimeWork.id)
.observe(yourLifecycle, yourObserver)

如果您不想将其绑定到LifecycleOwner,可以这样调用:

WorkManager.getInstance()
.getWorkInfoByIdLiveData(cloudSyncOneTimeWork.id)
.observeForever(yourObserver)

如果您这样做,当您想要时,您需要负责取消注册监听器


LiveData的问题在于需要LifecycleOwner才能正常工作。在您的Repository中没有这个对象,而我有工作调度。 - Євген Гарастович
这并不是真的,你可以使用livedata.observeForever(observer)而不需要指定LifecycleOwner (https://developer.android.com/reference/android/arch/lifecycle/LiveData#observeForever(android.arch.lifecycle.Observer%3CT%3E))。 - user2610355
我已经尝试过了。在某些设备上(嗨,三星),在我获得成功状态之前,它会被GC回收。 - Євген Гарастович

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