Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

workmanager listener called immediately

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?

like image 277
Євген Гарастович Avatar asked Nov 13 '18 12:11

Євген Гарастович


People also ask

How is AlarmManager different from WorkManager?

Alarms only. Unlike WorkManager, AlarmManager wakes a device from Doze mode. It is therefore not efficient in terms of power and resource management.

Is WorkManager deprecated?

This method is deprecated. Gets a LiveData of the last time all work was cancelled. Gets a ListenableFuture of the WorkInfo for a given work id.

How do I know if a manager is running or not?

You can check this by running getStatus() method on the WorkInfo instance.

Does WorkManager run on background thread?

WorkManager automatically runs it on a background thread (that you can override). Read more about threading in Worker instances in Threading in Worker.


1 Answers

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

like image 71
Codelicious Avatar answered Sep 29 '22 02:09

Codelicious