workmanager listener called immediately

青春壹個敷衍的年華 提交于 2021-02-06 09:21:07

问题


I need to have a callback upon Work completion from WorkManager (android.arch.work:work-runtime-ktx:1.0.0-alpha11). Yet the listener I'm adding is called immediately after work is scheduled.

Here's what I do:

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()

The UploadWorker class returns Success only after completing the whole upload sequence.

Here's the extension function code:

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)
}

When I add listeners to WorkResult, they are all called immediately, without waiting for the actual work to complete. Any thought on this?


回答1:


Until a proper solution is found for this (w/o GCed errors etc), a rudimentary approach could be to create another WorkRequest and chain it as the last work request to handle the state.

Ofcourse, you would have to handle the error states separately (And always return Result.success for each WorkRequest) to allow propagation through the chain.

This is by no means a sustainable approach, but rather a quick fix if necessary




回答2:


The problem is not observed if you get the result with liveData like this, instead of using ListenableFuture

WorkManager.getInstance()
.getWorkInfoByIdLiveData(cloudSyncOneTimeWork.id)
.observe(yourLifecycle, yourObserver)

If you don't want to tie it to a lifecycleowner you can call it like this :

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

If you do so you are responsible to unregister the listener when you want



来源:https://stackoverflow.com/questions/53281143/workmanager-listener-called-immediately

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!