Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cracking Kotlin Coroutines

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Cracking Kotlin Coroutines

The presentation was held at Droidcon Italy 2022 and was accompanied with live coding with examples from this GitHub repo https://github.com/dahlbergbob/cracking-coroutines-droidcon-it

Avatar for Bob Dahlberg

Bob Dahlberg

October 06, 2022
Tweet

More Decks by Bob Dahlberg

Other Decks in Programming

Transcript

  1. Cheating // clears the text field clear(optional:String = ””) //

    variants adds to the text field out(message:Any) // launches a coroutine viewModelScope.launch {}
  2. Suspension Suspension is one of the most central and fundamental

    part of Kotlin coroutines. Suspending is pausing Suspending is resuming Dividing the coroutine into smaller pieces
  3. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  4. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  5. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  6. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  7. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  8. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  9. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  10. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  11. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  12. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  13. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  14. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  15. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  16. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) }
  17. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) } // 0, 1, 6, 2, 4, 7, 3, 5
  18. Suspension fun order() { out(0) viewModelScope.launch { out(1) launch {

    out(2) delay(100) out(3) } launch { out(4) delay(100) out(5) } out(6) } out(7) } // 0, 1, 6, 2, 4, 7, 3, 5
  19. Suspension Lets look closer at the continuation in action with

    the suspendCancellableCoroutine function. fun simpleContinuation() { viewModelScope.launch { out(1) suspendCancellableCoroutine<Int> { out(2)
 it.resumeWith(Result.success(2)) } out(3) } }
  20. Suspension Use suspendCancellableCoroutine instead of suspendCoroutine, Useful when bridging between

    callbacks and coroutines. They are suspending functions, and as all suspending functions - they need to be called from a suspending function, and so on. So where to start?
  21. Scope A very small interface, only holding a reference to

    the context. Don't be afraid to create them - they are not dangerous. Look at viewModelScope to see an example used a lot But don't overuse them
  22. Context Simpli fi ed - A HashMap of Contexts We

    need a context - it de fi nes the rules for our coroutine We can override any value of the context Job, Dispatchers, CoroutineExceptionHandler, CoroutineName to name a few
  23. Structured concurrency An important and often overlooked part of coroutines.

    Our builders are extension functions to the CoroutineScope. Creating a new coroutine (invoking a builder) inherits the context and creates a parent/child relationship. Each coroutine awaits it’s children before completing
  24. Job

  25. Job Has a lifecycle dictating the state Each coroutine has

    it’s own job! It’s the only context that isn’t inherited 
 - each coroutine creates Its own instance with the inherited as its parent. Creating the hierarchy needed for structured concurrency
  26. Job Has a lifecycle dictating the state Each coroutine has

    it’s own job! It’s the only context that isn’t inherited 
 - each coroutine creates Its own instance with the inherited (or overridden) as its parent. Creating the hierarchy needed for structured concurrency
  27. Job wait children +-----+ start +--------+ complete +-------------+ finish +-----------+

    | New | -----> | Active | --------> | Completing | -------> | Completed | +-----+ +--------+ +-------------+ +-----------+ | cancel / fail | | +----------------+ | | V V +------------+ finish +-----------+ | Cancelling | -------------------------------> | Cancelled | +------------+ +-----------+
  28. Streams Flows Flows adhere to the general cooperative cancellation of

    coroutines. As usual, fl ow collection can be cancelled when the fl ow is suspended in a cancellable suspending function (like delay). Channels Note: Ticker channels are not currently integrated with structured concurrency and their api will change in the future.
  29. Suspension
 - They de fi ne the units of code


    - suspendCancellableCoroutine
 - Can only be called from other suspending functions Scope
 - They are the logical root of coroutines
 - Needed for builders
 - Cancel children, not the scope
 - Think of viewModelScope when in doubt. Structured concurrency
 - Understand it! Utilize it!
 - Even children with di ff erent dispatchers are awaited
 - Don’t think in callbacks. Job
 - The controller of structured concurrency
 - Understand the lifecycle
 - Be ware of creation to not outplay the structure
 - One coroutine - One Job Sum up
  30. Cancellation
 - They are collaborative - on suspension
 - Remember

    to re-trow them Exceptions
 - SupervisorJob / Job di ff erences
 - Use supervisorScope instead of creating jobs.
 - Propagates to the root (scope’s handler)
 - withContext(NonCancellable) Streams
 - Flows are built on top of coroutines
 - Channels are used to communicate between coroutines
 - Channels can’t broadcast
 - Mind context and use fl owOn
 - Think about order when collecting fl ows Sum up