DEV Community

loading...
Touchlab

Kotlin Coroutines Cheat Sheet

Kevin Schildhorn
I'm a mobile developer at Touchlab, working in native Android, iOS, and Kotlin Multiplatform.
Updated on ・3 min read

Recently I was refreshing myself on kotlin coroutines, as I had worked with them before but never fulled grasped all the ins and outs of coroutines, and I decided to make some notes while I was reading through the docs (https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html).
I figured they would be helpful to other kotlin developers. Note that these are quick notes I jotted down and isn't a fully grammatical tutorial-esque article.

Summary

Coroutines are light-weight threads

CoroutineScope - Used to build coroutines, contains CoroutineContext
Scope Types:

  • GlobalScope - Lifetime of the new coroutine is limited only by the lifetime of the whole application
  • CoroutineScope - Is destroyed after all launched children are completed
  • MainScope - Scope for UI applications and uses Dispatchers.Main

CoroutineContext - A collection of various elements. Contains Job and CoroutineDispatcher
CoroutineDispatcher - Determines the thread(s) to use
Dispatcher types:

  • Unconfined - I’m working in thread main (appropriate for coroutines which neither consume CPU time nor update any shared data (like UI) confined to a specific thread)
  • Default - I'm working in thread DefaultDispatcher-worker-1
  • newSingleThreadContext - I’m working in thread MyOwnThread
  • main runBlocking - I’m working in thread main
  • newSingleThreadContext() - Creates new thread, can be used to switch between using withContext

Launch

  • Launch is a coroutine builder that returns a Job
  • Launch inherits the context from the scope it’s launched from
  • Customizing Launch:
    • Can pass variables between threads using asContextElement
    • Can name Coroutines using CoroutineName

Async

  • Async is like launch, but returns a Deferred (i.e. future)
  • Async CoroutineStart.LAZY only starts when await is called

Cancellation

  • Jobs can be cancelled or call join, which works like pthread_join
  • Coroutine cancellation is cooperative, meaning if the coroutine isn’t checking if it’s cancelled then it won’t be cancelled
  • SupervisorJob is a job where cancellation is only propagated downwards
  • withTimeout creates a timeout for the coroutines (throws TimeoutCancellationException)
  • When cancelled:
    • Job throws an exception which can be handled with finally or catch (CancellationException)
    • All child coroutines are cancelled as well

Suspend

  • Suspend can be used inside coroutines, but can also use other suspending functions
  • If a coroutine builder is inside suspend function a CoroutineScope needs to be added as well

Blocking

  • runBlocking runs a new coroutine and blocks the current thread, interruptible until it’s completion
  • Delay is non blocking

Flow

  • Flow is an asynchronous stream of values
. Uses Emit and Collect to send and collect data
  • Flow runs in the context that is provided the collector
  • The code inside a flow isn’t run until the flow is collected
  • Flows can be cancelled with withTimeoutOrNull
  • Useful functions:
    • transform - customize data, such as emitting a header first
    • take - only take a certain amount of the flow
    • flowOn - change the context of preceding code
    • zip - combine multiple flows
    • catch - catch any exceptions of preceding code
    • onCompletion - perform any final tasks after the flow is done

Channel

  • Similar to a blocking queue, a way to transfer values between coroutines
  • Uses send and receive for normal values, produce and consume for streams
  • Channels can be closed to indicate no more elements are coming

Actor

  • Actor is an entity that can receive a class of messages using sealed classes. Meaning a consumer that takes in sealed classes

Let me know if I got anything wrong, or if I missed anything. Hope this helps!

Discussion (0)