Skip to content

Instantly share code, notes, and snippets.

@MartelliEnrico
Created January 23, 2018 13:39
Show Gist options
  • Save MartelliEnrico/58ea530d8bd31f35cecdde24633bcb3a to your computer and use it in GitHub Desktop.
Save MartelliEnrico/58ea530d8bd31f35cecdde24633bcb3a to your computer and use it in GitHub Desktop.
import android.arch.lifecycle.Lifecycle
import android.arch.lifecycle.LifecycleObserver
import android.arch.lifecycle.LifecycleOwner
import android.arch.lifecycle.OnLifecycleEvent
import kotlinx.coroutines.experimental.CoroutineStart
import kotlinx.coroutines.experimental.Deferred
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.newFixedThreadPoolContext
internal class CoroutineLifecycleListener(private val deferred: Deferred<*>) : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun cancelCoroutine() {
if (!deferred.isCancelled) {
deferred.cancel()
}
}
}
// CoroutineContext running on background threads.
internal val Background = newFixedThreadPoolContext(Runtime.getRuntime().availableProcessors() * 2, "Loader")
/**
* Creates a lazily started coroutine that runs <code>loader()</code>.
* The coroutine is automatically cancelled using the CoroutineLifecycleListener.
*/
fun <T> LifecycleOwner.load(loader: suspend () -> T): Deferred<T> {
val deferred = async(context = Background, start = CoroutineStart.LAZY) {
loader()
}
lifecycle.addObserver(CoroutineLifecycleListener(deferred))
return deferred
}
/**
* Extension function on <code>Deferred<T><code> that creates a launches a coroutine which
* will call <code>await()</code> and pass the returned value to <code>block()</code>.
*/
infix fun <T> Deferred<T>.then(block: suspend (T) -> Unit): Job {
return launch(context = UI) {
block([email protected]())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment