Reputation: 477
I have been digging into ListenableWorker
class to create a service using new workmanager. But nowhere have i found any examples. Any source which describes work manager, gives example of Worker
class which has a nice doWork
method but it doesn't meet my requirements. So i want your help to write a nice service using ListenableWorker
which can handle ListenableFuture
I have tried android developer's documentation and in their documentation, they have written about using guava and using concurrent-futures both of which don't provide any example to write a simple service. I also have watched the workmanager release video in which google engineers explain the new API but their examples are all in Kotlin and i don't get the classes to use.
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.concurrent.futures.CallbackToFutureAdapter;
import androidx.work.ListenableWorker;
import androidx.work.WorkerParameters;
import com.google.common.util.concurrent.ListenableFuture;
public class DistanceWorker extends ListenableWorker {
public DistanceWorker(Context context, WorkerParameters workerParameters){
super(context, workerParameters);
}
@NonNull
@Override
public ListenableFuture<Result> startWork() {
//what to write here ?
}
}
I just want to return a future and want to know how to resolve or reject that future when my work is done. Please help me understanding it.
Upvotes: 12
Views: 10488
Reputation: 4425
Sample code from Android Documentation.
class CallbackWorker(
context: Context,
params: WorkerParameters
) : ListenableWorker(context, params) {
override fun startWork(): ListenableFuture<Result> {
return CallbackToFutureAdapter.getFuture { completer ->
val callback = object : Callback {
var successes = 0
override fun onFailure(call: Call, e: IOException) {
completer.setException(e)
}
override fun onResponse(call: Call, response: Response) {
successes++
if (successes == 100) {
completer.set(Result.success())
}
}
}
repeat(100) {
downloadAsynchronously("https://example.com", callback)
}
callback
}
}
}
Reference:- https://developer.android.com/topic/libraries/architecture/workmanager/advanced/listenableworker
Upvotes: 0
Reputation: 10212
you can do like this
override fun startWork(): ListenableFuture<ListenableWorker.Result> {
// Do your work here
return CallbackToFutureAdapter.getFuture {
it.set(Result.success())
}
}
Upvotes: 5
Reputation: 684
I've also had questions on how to use ListenableWorkers using Kotlin. So I built this small example to retrieve location, which I believe it's the most common case to use it.
https://github.com/febaisi/ListenableWorkerExample
Here is a generic basic usage (not tested) - I believe it's just easier checking my project out where I added the complete tested version of this. I get data out of the worker in the Github project, and it's kind of hard to exemplify it here.
//Enqueue work
val anyWorkListenableWorker = OneTimeWorkRequest.Builder(AnyWorkListenableWorker::class.java).build()
workManagerInstance.enqueueUniqueWork("ANY_WORK", ExistingWorkPolicy.KEEP, anyWorkListenableWorker)
class AnyWorkListenableWorker(appContext: Context, workerParams: WorkerParameters)
: ListenableWorker(appContext, workerParams) {
private val future : ResolvableFuture<Result> = ResolvableFuture.create()
override fun startWork(): ListenableFuture<Result> {
//MAIN THREAD
CoroutineScope(Default).launch {
//Launch scope to do work out of the main thread
doAnyWork()
}
return future
}
private fun doAnyWork() {
//Do long work
future.set(Result.success())
}
}
Upvotes: 10
Reputation: 21104
Worker
, CoroutineWorker
or RxWorker
are all ListenableWorker
s. Here is a link to the source:
Upvotes: -2