Skip to content

Instantly share code, notes, and snippets.

@bmc08gt
Created October 21, 2021 18:59
Show Gist options
  • Save bmc08gt/06d19c8e80a8a349493ece1d46d88248 to your computer and use it in GitHub Desktop.
Save bmc08gt/06d19c8e80a8a349493ece1d46d88248 to your computer and use it in GitHub Desktop.
WorkManager state observation
interface WorkListener {
fun onConditionNotMet()
fun onStart()
fun onSuccess(data: Data)
fun onError(data: Data)
}
class WorkEnqueuer(val context: Context) {
private var listener: WorkListener? = null
private lateinit var lifecycleOwner: LifecycleOwner
private var precondition: () -> Boolean = { true }
/**
* Convenience function to create and set the [Listener].
*/
inline fun listen(
crossinline onConditionNotMet: () -> Unit = {},
crossinline onStart: () -> Unit = {},
crossinline onError: (data: Data) -> Unit = { _ -> },
crossinline onSuccess: (data: Data) -> Unit = { _ -> },
) = listen(object : WorkListener {
override fun onConditionNotMet() = onConditionNotMet()
override fun onStart() = onStart()
override fun onSuccess(data: Data) = onSuccess(data)
override fun onError(data: Data) = onError(data)
})
/**
* Set the [WorkListener].
*/
fun listen(listener: WorkListener?) = apply {
this.listener = listener
}
fun on(lifecycleOwner: LifecycleOwner) = apply {
this.lifecycleOwner = lifecycleOwner
}
fun onlyIf(precondition: () -> Boolean) = apply {
this.precondition = precondition
}
fun fire(uniqueWorkName: String, request: OneTimeWorkRequest) {
WorkManager.getInstance(context)
.enqueueUniqueWork(
uniqueWorkName,
ExistingWorkPolicy.KEEP,
request
)
}
fun enqueueAndAwait(
uniqueWorkName: String,
request: OneTimeWorkRequest
) {
val shouldEnqueue = precondition()
if (shouldEnqueue.not()) {
listener?.onConditionNotMet()
return
}
fire(uniqueWorkName, request)
WorkManager.getInstance(context).getWorkInfoByIdLiveData(request.id)
.observe(lifecycleOwner, { workInfo ->
if (workInfo != null) {
when (workInfo.state) {
WorkInfo.State.ENQUEUED -> {}
WorkInfo.State.RUNNING -> listener?.onStart()
WorkInfo.State.SUCCEEDED -> listener?.onSuccess(workInfo.outputData)
WorkInfo.State.FAILED -> listener?.onError(workInfo.outputData)
WorkInfo.State.BLOCKED -> {}
WorkInfo.State.CANCELLED -> {}
}
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment