SlideShare a Scribd company logo
Kotlin Coroutines - the new async
Bartłomiej Osmałek
Coroutines - the not-so-new async
Kotlin Coroutines
• Asynchronous

• Cooperative multitasking

• Single-threaded*

• Non-blocking
Non-blocking
Coroutine 1
Coroutine 2
Thread 1
Thread 2
waits for Coroutine 2
Coroutine 3
Dispatcher starts Coroutine 2
starts Coroutine 3
Show me the code!
fun loadDataForUI() {
showOnUi(getSomeValue())
}
fun getSomeValue(): Int {
//some serious calculation
return 5
}
fun loadDataForUI() {
showOnUi(getSomeValue())
}
suspend fun getSomeValue(): Int {
delay(timeMillis = 5000)
return 5
}
fun loadDataForUI() = runBlocking {
showOnUi(getSomeValue())
}
suspend fun getSomeValue(): Int {
delay(timeMillis = 5000)
return 5
}
suspend fun loadDataForUI() {
showOnUi(getSomeValue())
}
suspend fun getSomeValue(): Int {
delay(timeMillis = 5000)
return 5
}
suspend fun loadDataForUI() {
val someValue = getSomeValue()
showOnUi(someValue)
}
suspend fun getSomeValue(): Int {…}
suspend fun loadDataForUI() {
val someValue = getSomeValue()
//do something else
showOnUi(someValue)
}
suspend fun getSomeValue(): Int {…}
suspend fun loadDataForUI() = coroutineScope {
val someValue = async { getSomeValue() }
//do something else
showOnUi(someValue.await())
}
suspend fun getSomeValue(): Int {…}
launch async
Return value Job Deferred<T>
Suspend till finish join(): Unit await(): T
Error handling Propagate to parent
Throws when called
await
suspend fun loadDataForUI() = coroutineScope {
val someValue = async { getSomeValue() }
//do something else
showOnUi(someValue.await())
}
suspend fun getSomeValue(): Int {…}
Each coroutine needs a Coroutine Scope
coroutineScope
• Waits for all child coroutines to complete

• Cancels other child coroutines if any fails

• Provides CoroutineContext

• Can limit coroutine lifetime
abstract class BaseViewModel : ViewModel(), CoroutineScope {
override val coroutineContext = Dispatchers.IO + Job()
@CallSuper
override fun onCleared() {
coroutineContext.cancel()
}
}
CoroutineContext
• Provides parent job

• Provides error handler

• Provides dispatcher
Dispatcher
• Provides threads for coroutine execution*

• Available dispatchers:

‣ Dispatchers.Default

‣ Dispatchers.Main

‣ Dispatchers.IO

‣ Dispatchers.Unconfined
Unconfined can be tricky
fun main(args: Array<String>) = runBlocking<Unit> {
launch {
log("Hello")
delay(100)
log("World")
}
log("Launched!")
}
Output:
[main] Launched!
[main] Hello
[main] World
Unconfined can be tricky
fun main(args: Array<String>) = runBlocking<Unit> {
launch(Dispatchers.Unconfined) {
log("Hello")
delay(100)
log("World")
}
log("Launched!")
}
Output:
[main] Hello
[main] Launched!
[kotlinx.coroutines.DefaultExecutor] World
Unconfined can be tricky
fun main(args: Array<String>) = runBlocking<Unit> {
launch(Dispatchers.Unconfined) {
val job = launch(Dispatchers.IO) {
log("do nothing")
}
log("Hello")
job.join()
log("World")
}
log("Launched!")
}
Output:
[main] Hello
[DefaultDispatcher-worker-1] do nothing
[main] World
[main] Launched!
Unconfined can be tricky
fun main(args: Array<String>) = runBlocking<Unit> {
launch(Dispatchers.Unconfined) {
val job = launch(Dispatchers.IO) {
log("do nothing")
delay(100)
}
log("Hello")
job.join()
log("World")
}
log("Launched!")
}
Output:
[DefaultDispatcher-worker-1] do nothing
[main] Hello
[main] Launched!
[DefaultDispatcher-worker-1] World
Canceling coroutine
Canceling coroutine
fun main(args: Array<String>) = runBlocking<Unit> {
var job = Job()
job = launch {
log("Hello")
delay(100)
log("World")
}
log("Launched!")
job.cancel()
}
Output:
[main] Launched!
Canceling coroutine
fun main(args: Array<String>) = runBlocking<Unit> {
var job = Job()
job = launch {
log("Hello")
job.cancel()
delay(100)
log("World")
}
log("Launched!")
}
Output:
[main] Launched!
[main] Hello
Canceling coroutine
fun main(args: Array<String>) = runBlocking<Unit> {
var job = Job()
job = launch {
log("Hello")
job.cancel()
Thread.sleep(100)
log("World")
}
log("Launched!")
}
Output:
[main] Launched!
[main] Hello
[main] World
Canceling coroutine
fun main(args: Array<String>) = runBlocking<Unit> {
var job = Job()
job = launch {
log("Hello")
job.cancel()
Thread.sleep(100)
yield()
log("World")
}
log("Launched!")
}
Output:
[main] Launched!
[main] Hello
Ok, but give some real use cases!
//in ViewModel
val appId = async(start = CoroutineStart.LAZY) { // Dispatchers.IO
pairingInteractor.fetchAppId()
}
//in Fragment
private fun fetchAppId() {
launch { // Dispatchers.Main
val appId = viewModel.appId.await()
appIdTextView.text = appId
}
}
suspend fun updateAndSynchronize() = coroutineScope {
val appStatus = statusRepository.fetchAppStatus(forceRefresh = true)
val jobs = appStatus.versions
.forEach { (versionable, versionFromAppStatus) ->
val updater = updaterFactory.create(versionable)
if (versionFromAppStatus > updater.getCurrentVersion()) {
launch { updater.update(versionFromAppStatus) }
}
}
}
suspend fun checkServerIsValid(serverUrl: String): ServerCheckResult {
return try {
serverRepository.getServerInfo(serverUrl)
ServerCheckResult.VALID_SERVER
} catch (e: Exception) {
when (e) {
is IllegalArgumentException -> ServerCheckResult.INVALID_URL
is JsonEncodingException -> ServerCheckResult.INVALID_SERVER
is IOException -> ServerCheckResult.NO_CONNECTION
else -> ServerCheckResult.INVALID_SERVER
}
}
}
suspend fun checkServerIsValid(serverUrl: String): Result<ServerCheckResult> {
return runCatching {
serverRepository.getServerInfo(serverUrl)
ServerCheckResult.VALID_SERVER
}
}
Bartłomiej Osmałek
Android Developer @ Droids on Roids

Co-organizer @ GDG Wrocław
Nonda95
@nonda95
nonda1995
bartlomiej-osmalek
Thanks!

More Related Content

PDF
Introduction to Kotlin coroutines
PPTX
JavaScript Engines and Event Loop
PDF
Introduction to kotlin coroutines
PDF
Linux Profiling at Netflix
PPT
JavaScript Event Loop
PDF
Improving app performance with Kotlin Coroutines
PDF
Spring Boot Actuator 2.0 & Micrometer
PPTX
The Java memory model made easy
Introduction to Kotlin coroutines
JavaScript Engines and Event Loop
Introduction to kotlin coroutines
Linux Profiling at Netflix
JavaScript Event Loop
Improving app performance with Kotlin Coroutines
Spring Boot Actuator 2.0 & Micrometer
The Java memory model made easy

What's hot (20)

PPTX
Introduction to Apache Camel
PDF
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
PDF
Container Performance Analysis
PPTX
JavaScript Event Loop
PDF
FreeSWITCH as a Microservice
PDF
Reactive Programming for a demanding world: building event-driven and respons...
PPTX
K8s beginner 2_advanced_ep02_201904221130_post
PPT
jpa-hibernate-presentation
PPTX
All you need to know about the JavaScript event loop
PDF
Coroutines for Kotlin Multiplatform in Practise
PDF
Kotlin Coroutines in Practice @ KotlinConf 2018
PPTX
JPA For Beginner's
PPTX
Coroutines in Kotlin
PDF
Threads 04 Variáveis atômicas
PDF
[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka
PDF
Kubernetes dealing with storage and persistence
ODP
Xke spring boot
PDF
History & Practices for UniRx(EN)
PDF
Java Performance Analysis on Linux with Flame Graphs
Introduction to Apache Camel
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
Container Performance Analysis
JavaScript Event Loop
FreeSWITCH as a Microservice
Reactive Programming for a demanding world: building event-driven and respons...
K8s beginner 2_advanced_ep02_201904221130_post
jpa-hibernate-presentation
All you need to know about the JavaScript event loop
Coroutines for Kotlin Multiplatform in Practise
Kotlin Coroutines in Practice @ KotlinConf 2018
JPA For Beginner's
Coroutines in Kotlin
Threads 04 Variáveis atômicas
[2019] 바르게, 빠르게! Reactive를 품은 Spring Kafka
Kubernetes dealing with storage and persistence
Xke spring boot
History & Practices for UniRx(EN)
Java Performance Analysis on Linux with Flame Graphs
Ad

Similar to Kotlin Coroutines - the new async (20)

PDF
Quick Introduction to Kotlin Coroutine for Android Dev
PDF
Kotlin from-scratch 3 - coroutines
PDF
Kotlin - Coroutine
PDF
Tackling Asynchrony with Kotlin Coroutines
PDF
Kotlin coroutine - the next step for RxJava developer?
PPTX
Coroutines talk ppt
PDF
Kotlin Coroutines and Android sitting in a tree
PDF
Coroutines
PPTX
2019-01-29 - Demystifying Kotlin Coroutines
PDF
Should it be routine to use coroutines?
PDF
Coroutines in Kotlin
PDF
Programação assíncrona utilizando Coroutines
PDF
Kotlin coroutines
PDF
Kotlin Coroutines and Android sitting in a tree - 2018 version
PPTX
Exploring Kotlin
PDF
Lean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, Gett
PDF
Aplicações assíncronas no Android com
Coroutines & Jetpack
PDF
Current State of Coroutines
PDF
Asynchronous Programming in Kotlin with Coroutines
PDF
Coroutines in Kotlin. In-depth review
Quick Introduction to Kotlin Coroutine for Android Dev
Kotlin from-scratch 3 - coroutines
Kotlin - Coroutine
Tackling Asynchrony with Kotlin Coroutines
Kotlin coroutine - the next step for RxJava developer?
Coroutines talk ppt
Kotlin Coroutines and Android sitting in a tree
Coroutines
2019-01-29 - Demystifying Kotlin Coroutines
Should it be routine to use coroutines?
Coroutines in Kotlin
Programação assíncrona utilizando Coroutines
Kotlin coroutines
Kotlin Coroutines and Android sitting in a tree - 2018 version
Exploring Kotlin
Lean way write asynchronous code with Kotlin’s coroutines - Ronen Sabag, Gett
Aplicações assíncronas no Android com
Coroutines & Jetpack
Current State of Coroutines
Asynchronous Programming in Kotlin with Coroutines
Coroutines in Kotlin. In-depth review
Ad

Recently uploaded (20)

PDF
System and Network Administraation Chapter 3
PPTX
Computer Software and OS of computer science of grade 11.pptx
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PPTX
Transform Your Business with a Software ERP System
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Digital Strategies for Manufacturing Companies
PPTX
Odoo POS Development Services by CandidRoot Solutions
PPTX
Introduction to Artificial Intelligence
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Designing Intelligence for the Shop Floor.pdf
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
System and Network Administration Chapter 2
PDF
Nekopoi APK 2025 free lastest update
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
L1 - Introduction to python Backend.pptx
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
medical staffing services at VALiNTRY
System and Network Administraation Chapter 3
Computer Software and OS of computer science of grade 11.pptx
Wondershare Filmora 15 Crack With Activation Key [2025
Upgrade and Innovation Strategies for SAP ERP Customers
Transform Your Business with a Software ERP System
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Digital Strategies for Manufacturing Companies
Odoo POS Development Services by CandidRoot Solutions
Introduction to Artificial Intelligence
Odoo Companies in India – Driving Business Transformation.pdf
Designing Intelligence for the Shop Floor.pdf
Reimagine Home Health with the Power of Agentic AI​
System and Network Administration Chapter 2
Nekopoi APK 2025 free lastest update
Design an Analysis of Algorithms II-SECS-1021-03
Operating system designcfffgfgggggggvggggggggg
L1 - Introduction to python Backend.pptx
Softaken Excel to vCard Converter Software.pdf
Navsoft: AI-Powered Business Solutions & Custom Software Development
medical staffing services at VALiNTRY

Kotlin Coroutines - the new async

  • 1. Kotlin Coroutines - the new async Bartłomiej Osmałek
  • 2. Coroutines - the not-so-new async
  • 3. Kotlin Coroutines • Asynchronous • Cooperative multitasking • Single-threaded* • Non-blocking
  • 4. Non-blocking Coroutine 1 Coroutine 2 Thread 1 Thread 2 waits for Coroutine 2 Coroutine 3 Dispatcher starts Coroutine 2 starts Coroutine 3
  • 5. Show me the code!
  • 6. fun loadDataForUI() { showOnUi(getSomeValue()) } fun getSomeValue(): Int { //some serious calculation return 5 }
  • 7. fun loadDataForUI() { showOnUi(getSomeValue()) } suspend fun getSomeValue(): Int { delay(timeMillis = 5000) return 5 }
  • 8. fun loadDataForUI() = runBlocking { showOnUi(getSomeValue()) } suspend fun getSomeValue(): Int { delay(timeMillis = 5000) return 5 }
  • 9. suspend fun loadDataForUI() { showOnUi(getSomeValue()) } suspend fun getSomeValue(): Int { delay(timeMillis = 5000) return 5 }
  • 10. suspend fun loadDataForUI() { val someValue = getSomeValue() showOnUi(someValue) } suspend fun getSomeValue(): Int {…}
  • 11. suspend fun loadDataForUI() { val someValue = getSomeValue() //do something else showOnUi(someValue) } suspend fun getSomeValue(): Int {…}
  • 12. suspend fun loadDataForUI() = coroutineScope { val someValue = async { getSomeValue() } //do something else showOnUi(someValue.await()) } suspend fun getSomeValue(): Int {…}
  • 13. launch async Return value Job Deferred<T> Suspend till finish join(): Unit await(): T Error handling Propagate to parent Throws when called await
  • 14. suspend fun loadDataForUI() = coroutineScope { val someValue = async { getSomeValue() } //do something else showOnUi(someValue.await()) } suspend fun getSomeValue(): Int {…}
  • 15. Each coroutine needs a Coroutine Scope
  • 16. coroutineScope • Waits for all child coroutines to complete • Cancels other child coroutines if any fails • Provides CoroutineContext • Can limit coroutine lifetime
  • 17. abstract class BaseViewModel : ViewModel(), CoroutineScope { override val coroutineContext = Dispatchers.IO + Job() @CallSuper override fun onCleared() { coroutineContext.cancel() } }
  • 18. CoroutineContext • Provides parent job • Provides error handler • Provides dispatcher
  • 19. Dispatcher • Provides threads for coroutine execution* • Available dispatchers: ‣ Dispatchers.Default ‣ Dispatchers.Main ‣ Dispatchers.IO ‣ Dispatchers.Unconfined
  • 20. Unconfined can be tricky fun main(args: Array<String>) = runBlocking<Unit> { launch { log("Hello") delay(100) log("World") } log("Launched!") } Output: [main] Launched! [main] Hello [main] World
  • 21. Unconfined can be tricky fun main(args: Array<String>) = runBlocking<Unit> { launch(Dispatchers.Unconfined) { log("Hello") delay(100) log("World") } log("Launched!") } Output: [main] Hello [main] Launched! [kotlinx.coroutines.DefaultExecutor] World
  • 22. Unconfined can be tricky fun main(args: Array<String>) = runBlocking<Unit> { launch(Dispatchers.Unconfined) { val job = launch(Dispatchers.IO) { log("do nothing") } log("Hello") job.join() log("World") } log("Launched!") } Output: [main] Hello [DefaultDispatcher-worker-1] do nothing [main] World [main] Launched!
  • 23. Unconfined can be tricky fun main(args: Array<String>) = runBlocking<Unit> { launch(Dispatchers.Unconfined) { val job = launch(Dispatchers.IO) { log("do nothing") delay(100) } log("Hello") job.join() log("World") } log("Launched!") } Output: [DefaultDispatcher-worker-1] do nothing [main] Hello [main] Launched! [DefaultDispatcher-worker-1] World
  • 25. Canceling coroutine fun main(args: Array<String>) = runBlocking<Unit> { var job = Job() job = launch { log("Hello") delay(100) log("World") } log("Launched!") job.cancel() } Output: [main] Launched!
  • 26. Canceling coroutine fun main(args: Array<String>) = runBlocking<Unit> { var job = Job() job = launch { log("Hello") job.cancel() delay(100) log("World") } log("Launched!") } Output: [main] Launched! [main] Hello
  • 27. Canceling coroutine fun main(args: Array<String>) = runBlocking<Unit> { var job = Job() job = launch { log("Hello") job.cancel() Thread.sleep(100) log("World") } log("Launched!") } Output: [main] Launched! [main] Hello [main] World
  • 28. Canceling coroutine fun main(args: Array<String>) = runBlocking<Unit> { var job = Job() job = launch { log("Hello") job.cancel() Thread.sleep(100) yield() log("World") } log("Launched!") } Output: [main] Launched! [main] Hello
  • 29. Ok, but give some real use cases!
  • 30. //in ViewModel val appId = async(start = CoroutineStart.LAZY) { // Dispatchers.IO pairingInteractor.fetchAppId() } //in Fragment private fun fetchAppId() { launch { // Dispatchers.Main val appId = viewModel.appId.await() appIdTextView.text = appId } }
  • 31. suspend fun updateAndSynchronize() = coroutineScope { val appStatus = statusRepository.fetchAppStatus(forceRefresh = true) val jobs = appStatus.versions .forEach { (versionable, versionFromAppStatus) -> val updater = updaterFactory.create(versionable) if (versionFromAppStatus > updater.getCurrentVersion()) { launch { updater.update(versionFromAppStatus) } } } }
  • 32. suspend fun checkServerIsValid(serverUrl: String): ServerCheckResult { return try { serverRepository.getServerInfo(serverUrl) ServerCheckResult.VALID_SERVER } catch (e: Exception) { when (e) { is IllegalArgumentException -> ServerCheckResult.INVALID_URL is JsonEncodingException -> ServerCheckResult.INVALID_SERVER is IOException -> ServerCheckResult.NO_CONNECTION else -> ServerCheckResult.INVALID_SERVER } } }
  • 33. suspend fun checkServerIsValid(serverUrl: String): Result<ServerCheckResult> { return runCatching { serverRepository.getServerInfo(serverUrl) ServerCheckResult.VALID_SERVER } }
  • 34. Bartłomiej Osmałek Android Developer @ Droids on Roids Co-organizer @ GDG Wrocław Nonda95 @nonda95 nonda1995 bartlomiej-osmalek Thanks!