Skip to content

Instantly share code, notes, and snippets.

View omkar-tenkale's full-sized avatar
☸️
Planning

Omkar Tenkale omkar-tenkale

☸️
Planning
View GitHub Profile
suspend fun withContext(dispatcher: Dispatcher, block: suspend () -> Unit) {
// Suspend current coroutine
suspendCoroutineUninterceptedOrReturn<Unit> { cont ->
// Define completion callback for new coroutine
val callback = object : Continuation<Unit> {
override val context = EmptyCoroutineContext
override fun resumeWith(result: Result<Unit>) {
// Resume the previous coroutine
when (cont.context as Dispatcher) {
launch(Dispatcher.Main){
println("Download Started")
launch(Dispatcher.Background){
println("Download in progress")
downloader.download(url)
}
println("Download Complete")
}
// Output
import java.lang.Exception
import kotlin.concurrent.thread
import java.util.concurrent.Executors
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
fun launch(dispatcher: Dispatcher, block: suspend () -> Unit) {
val callback = object : Continuation<Unit> {
// Passing dispatcher as CoroutineContext
override val context: CoroutineContext = dispatcher
override fun resumeWith(result: Result<Unit>) {}
}
val coroutine = block.createCoroutineUnintercepted(callback)
when (dispatcher) {
Dispatcher.Main -> Handler(Looper.getMainLooper()).post {
coroutine.resumeWith(Result.success(Unit))
sealed class Dispatcher: CoroutineContext.Element {
object Main : Dispatcher()
object Background : Dispatcher()
override val key = DispatcherKey
}
object DispatcherKey: CoroutineContext.Key<Dispatcher>{}
fun main() {
launch(Dispatcher.Background) {
fun1(Dispatcher.Background)
}
}
suspend fun fun1(dispatcher: Dispatcher){
...
fun2(dispatcher)
...
button.setOnClickListener{
launch(Dispatcher.Main) {
textView.text = "Downloading file" // Runs on main thread
suspendCoroutineUninterceptedOrReturn<Unit> { cont ->
thread {
downloader.download("http://example.com/file.txt") // Runs on Background thread
cont.resumeWith(Result.success(Unit))
}
COROUTINE_SUSPENDED
}
sealed class Dispatcher {
object Main : Dispatcher()
object Background : Dispatcher()
}
fun launch(dispatcher: Dispatcher, block: suspend () -> Unit) {
//Define a callback
val callback = object : Continuation<Unit> {
override val context = EmptyCoroutineContext
fun launch(block: suspend () -> Unit) {
val callback = object : Continuation<Unit> {
override val context: CoroutineContext = EmptyCoroutineContext
override fun resumeWith(result: Result<Unit>) {}
}
block.createCoroutineUnintercepted(callback).resumeWith(Result.success(Unit))
}
...
import kotlin.concurrent.thread
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.intrinsics.createCoroutineUnintercepted
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
fun main() {
// Define a suspend lambda