SlideShare una empresa de Scribd logo
Kotlin Coroutines:
Multi-threading made easy
Arthur Nagy
Halcyon Mobile
Agenda
1. What are coroutines
2. Coroutines in Android
3. Why use coroutines
What are coroutines
“coroutines are computations that can be suspended
without blocking a thread.”
● Not a new concept, introduced in the `60s
● Adopted by multiple programming languages
● Coroutines in Kotlin:
○ minimal low-level APIs in its standard library
○ kotlinx.coroutines libraries
What are coroutines
● Terminology :
○ Coroutine
○ Suspending function
○ Coroutine builder
○ Continuation
○ Coroutine context
Coroutine
● An instance of suspendable computation
● Similar to a thread (light-weight thread)
● Also similar to a future or promise
Suspending functions
● Functions which suspend a coroutine execution
● suspend keyword
● Suspending functions can be used:
○ Inside other functions marked with the suspend keyword
○ Inside a coroutine
● suspendCoroutine
○ Bridge between coroutine suspension and callback world
Suspending functions
/**
* Obtains the current continuation instance
* inside suspend functions and suspends
* currently running coroutine.
*/
suspend inline fun <T> suspendCoroutine(
crossinline block: (Continuation<T>) -> Unit): T =
Suspending functions
public interface Continuation<in T> {
public val context: CoroutineContext
public fun resume(value: T)
public fun resumeWithException(exception: Throwable)
}
Suspending functions
suspend fun firstFun(): ResultType = suspendCoroutine { continuation ->
// do some heavy work
// resume the coroutine continuation with a result:
continuation.resume(result)
// or if there was an error:
continuation.resumeWithException(exception)
}
Coroutine builders
● Functions which start a coroutine
● Bridge between non-coroutine & coroutine world
● Most common coroutine builders:
○ launch
○ async
○ withContext
Coroutine builders
launch {
// everything inside happens on
// a background thread pool
}
// continue app operations
Coroutine builders
fun launch(
context: CoroutineContext = Dispatchers.Default,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job
Coroutine builders
val result: Deferred<T> = async {
// do stuff on the background thread
// which returns a value T when done
}
result.await()
Coroutine builders
val result: T = withContext(BACKGROUND) {
// do stuff on the background thread
// which returns a value T when done
}
Coroutines in Android
Coroutines in Android
kotlin {
experimental {
coroutines 'enable'
}
}
dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.25.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.25.0'
}
class BlurActivity : AppCompatActivity() {
...
override fun onActivityResult(requestC: Int, resultC: Int, data: Intent?) {
val imageUri = data?.data
launch(UI) {
val resultImage = withContext(BACKGROUND) {
blurImage(imageUri)
}
viewBinding.image.setImageURI(resultImage)
viewModel.uploadImage(resultImage)
}
}
...
}
suspend fun blurImage(imageUri: Uri): Uri = suspendCoroutine { continuation ->
try {
val imageBitmap = getBitmapFromImageUri(imageUri)
val blurredImage = applyBlurOnBitmap(imageBitmap)
val blurredImageFile = saveBitmapToTemporaryFile(blurredImage)
continuation.resume(blurredImageFile)
} catch (e: Exception) {
continuation.resumeWithException(e)
}
}
class BlurActivity : AppCompatActivity() {
...
override fun onActivityResult(requestC: Int, resultC: Int, data: Intent?) {
val imageUri = data?.data
launch(UI) {
val resultImage = withContext(BACKGROUND) {
blurImage(imageUri)
}
viewBinding.image.setImageURI(resultImage)
viewModel.uploadImage(resultImage)
}
}
...
}
class BlurViewModel(
private val restApiService: RestApiService
) : ViewModel() {
...
fun uploadImage(imageUri: Uri) {
// update UI state, i.e: show progress, etc
launch(BACKGROUND) {
val imageFile = File(imageUri.path)
val imageFilePart = createImagePart(imageFile)
val response = restApiService.uploadBlurredImage(imageFilePart).await()
// use our response to update UI state, etc.
}
}
...
}
restApiService.uploadBlurredImage(imageFilePart).enqueue(Callback<> {
override fun onResponse(call, response) {
if (response.isSuccessful){
val blurResponse = response.body()!!
// use our response to update UI state, etc.
}
}
override fun onFailure(call, throwable) {
}
})
launch(BACKGROUND) {
val response = restApiService.uploadBlurredImage(imageFilePart).await()
}
interface RestApiService {
@Multipart
@POST("/blurred_image")
fun uploadBlurredImage(@Part file: Part): Call<BlurResponse>
}
suspend fun <T> Call<T>.await(): T = suspendCoroutine { continuation ->
enqueue(object: Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
if (response.isSuccessful) {
continuation.resume(response.body()!!)
} else {
continuation.resumeWithException(RequestException(response.message()))
}
}
override fun onFailure(call: Call<T>, t: Throwable) {
continuation.resumeWithException(t)
}
})
}
What about Android
lifecycle handling &
cancelation?
class BlurActivity : AppCompatActivity() {
...
launch(UI) {
val resultImage = withContext(BACKGROUND) {
blurImage(imageUri)
}
}
...
}
class BlurActivity : AppCompatActivity() {
...
val job = launch(UI) {
val resultImage = withContext(BACKGROUND) {
blurImage(imageUri)
}
}
...
override fun onStop() {
super.onStop()
job.cancel()
}
}
class CoroutineLifecycleObserver : LifecycleObserver {
var parentJob: Job = Job()
@OnLifecycleEvent(Lifecycle.Event.ON_START) fun start() {
if (parentJob.isCompleted) {
parentJob = Job()
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun cancel() {
if (parentJob.isActive) {
parentJob.cancel()
}
}
}
gist.github.com/chrisbanes/152d325211401843326068c24e0d11b1
class BlurActivity : AppCompatActivity() {
private val coroutineObserver = CoroutineLifecycleObserver()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
lifecycle.addObserver(coroutineObserver)
}
launch(context = UI, parent = coroutineObserver.job) {
val resultImage = withContext(BACKGROUND) {
blurImage(imageUri)
}
}
}
open class CoroutineViewModel : ViewModel() {
private val parentJob = Job()
override fun onCleared() {
super.onCleared()
parentJob.cancel()
}
protected fun launchWithParent(
context: CoroutineContext = BACKGROUND,
block: suspend CoroutineScope.() -> Unit
) = launch(context = context, parent = parentJob, block = block)
}
class BlurViewModel(
private val restApiService: RestApiService
) : CoroutineViewModel() {
fun uploadImage(imageUri: Uri) {
launchWithParent(BACKGROUND) {
...
}
}
}
Why use coroutines
● Asynchronous code sequentially
● No more callback-hell
asyncOperation(object: Callback {
fun onSuccess(result) {
anotherOne(result, object: Callback {
fun onSuccess(secondResult){
lastOne(secondResult, object: Callback {
fun onSuccess(thirdResult){
useResult(thirdResult)
}
fun onError(exception){
handleError(exception)
}
})
}
fun onError(exception){
handleError(exception)
}
})
}
fun onError(exception) {
handleError(exception)
}
})
Why use coroutines
● Asynchronous code sequentially
● No more callback-hell
● “It’s experimental, we can’t use it!”
● “We already have so many options, why use this one?!”
Why use coroutines
val blurAsyncTask = object : AsyncTask<Uri, Int, Uri>() {
override fun doInBackground(vararg params: Uri?): Uri {
return blurImage(params)
}
override fun onPostExecute(result: Uri?) {
viewBinding.image.setImageURI(result)
viewModel.uploadImage(result)
}
}
blurAsyncTask.execute(imageUri)
Why use coroutines
private val executors = Executors.newCachedThreadPool()
fun uploadImage(imageUri: Uri) {
executors.execute {
val imageFile = File(imageUri.path)
val imageFilePart = createImagePart(imageFile)
restApiService.uploadBlurredImage(imageFilePart).enqueue(Callback<> {
override fun onResponse(response: Response<>) {
// use the response to update state, etc.
}
override fun onFailure(t: Throwable) {
}
})
}
}
Why use coroutines
disposables.add(Single
.fromCallable { blurImage(imageUri) }
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ resultImage ->
viewBinding.image.setImageURI(resultImage)
viewModel.uploadImage(resultImage)
},{ error ->
})
)
Why use coroutines
fun uploadImage(imageUri: Uri) {
disposables.add(Single.fromCallable {
val imageFile = File(imageUri.path)
createImagePart(imageFile)
}.flatMap(restApiService::uploadBlurredImage)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ blurResponse ->
//update UI state, etc.
}, { error ->
})
)
}
● There’s a lot more:
○ Exception handling, channels, actors, etc.
● Resources:
○ kotlinlang.org/docs/reference/coroutines.html
○ github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-infor
mal.md
○ github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md
○ gist.github.com/chrisbanes/152d325211401843326068c24e0d11b1
○ github.com/gildor/kotlin-coroutines-retrofit
Thank you!
● twitter.com/android_halcyon
● medium.com/halcyon-mobile
● halcyonmobile.com
● arthurnagy.me

Más contenido relacionado

La actualidad más candente

Koin Quickstart
Koin QuickstartKoin Quickstart
Koin Quickstart
Matthew Clarke
 
Deep dive into Android async operations
Deep dive into Android async operationsDeep dive into Android async operations
Deep dive into Android async operations
Mateusz Grzechociński
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
Ynon Perek
 
Technical Deep Dive into the New Prefab System
Technical Deep Dive into the New Prefab SystemTechnical Deep Dive into the New Prefab System
Technical Deep Dive into the New Prefab System
Unity Technologies
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
ICS
 
Twins: OOP and FP
Twins: OOP and FPTwins: OOP and FP
Twins: OOP and FP
RichardWarburton
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
Leonardo Borges
 
QThreads: Are You Using Them Wrong?
QThreads: Are You Using Them Wrong? QThreads: Are You Using Them Wrong?
QThreads: Are You Using Them Wrong?
ICS
 
Intro to Clojure's core.async
Intro to Clojure's core.asyncIntro to Clojure's core.async
Intro to Clojure's core.async
Leonardo Borges
 
Intro to QML / Declarative UI
Intro to QML / Declarative UIIntro to QML / Declarative UI
Intro to QML / Declarative UI
OpenBossa
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
Michael Girouard
 
Qt for beginners part 1 overview and key concepts
Qt for beginners part 1   overview and key conceptsQt for beginners part 1   overview and key concepts
Qt for beginners part 1 overview and key concepts
ICS
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
Ivan Dolgushin
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simpler
Alexander Mostovenko
 
Qt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt QuickQt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt Quick
ICS
 
Introducing the New Prefab Workflow - Unite LA
Introducing the New Prefab Workflow - Unite LAIntroducing the New Prefab Workflow - Unite LA
Introducing the New Prefab Workflow - Unite LA
Unity Technologies
 
Java libraries you can't afford to miss
Java libraries you can't afford to missJava libraries you can't afford to miss
Java libraries you can't afford to miss
Andres Almiray
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
Duoyi Wu
 
Exploring Kotlin
Exploring KotlinExploring Kotlin
Exploring Kotlin
Atiq Ur Rehman
 
Current State of Coroutines
Current State of CoroutinesCurrent State of Coroutines
Current State of Coroutines
Guido Pio Mariotti
 

La actualidad más candente (20)

Koin Quickstart
Koin QuickstartKoin Quickstart
Koin Quickstart
 
Deep dive into Android async operations
Deep dive into Android async operationsDeep dive into Android async operations
Deep dive into Android async operations
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
 
Technical Deep Dive into the New Prefab System
Technical Deep Dive into the New Prefab SystemTechnical Deep Dive into the New Prefab System
Technical Deep Dive into the New Prefab System
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
 
Twins: OOP and FP
Twins: OOP and FPTwins: OOP and FP
Twins: OOP and FP
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
QThreads: Are You Using Them Wrong?
QThreads: Are You Using Them Wrong? QThreads: Are You Using Them Wrong?
QThreads: Are You Using Them Wrong?
 
Intro to Clojure's core.async
Intro to Clojure's core.asyncIntro to Clojure's core.async
Intro to Clojure's core.async
 
Intro to QML / Declarative UI
Intro to QML / Declarative UIIntro to QML / Declarative UI
Intro to QML / Declarative UI
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
Qt for beginners part 1 overview and key concepts
Qt for beginners part 1   overview and key conceptsQt for beginners part 1   overview and key concepts
Qt for beginners part 1 overview and key concepts
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simpler
 
Qt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt QuickQt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt Quick
 
Introducing the New Prefab Workflow - Unite LA
Introducing the New Prefab Workflow - Unite LAIntroducing the New Prefab Workflow - Unite LA
Introducing the New Prefab Workflow - Unite LA
 
Java libraries you can't afford to miss
Java libraries you can't afford to missJava libraries you can't afford to miss
Java libraries you can't afford to miss
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
Exploring Kotlin
Exploring KotlinExploring Kotlin
Exploring Kotlin
 
Current State of Coroutines
Current State of CoroutinesCurrent State of Coroutines
Current State of Coroutines
 

Similar a droidcon Transylvania - Kotlin Coroutines

Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
Nelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
Nelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
Nelson Glauber Leal
 
Kotlin Generation
Kotlin GenerationKotlin Generation
Kotlin Generation
Minseo Chayabanjonglerd
 
Building Mobile Apps with Android
Building Mobile Apps with AndroidBuilding Mobile Apps with Android
Building Mobile Apps with Android
Kurt Renzo Acosta
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
Nelson Glauber Leal
 
Kotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesKotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutines
Franco Lombardo
 
Practical tips for building apps with kotlin
Practical tips for building apps with kotlinPractical tips for building apps with kotlin
Practical tips for building apps with kotlin
Adit Lal
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in Practise
Christian Melchior
 
Performance #6 threading
Performance #6  threadingPerformance #6  threading
Performance #6 threading
Vitali Pekelis
 
Save time with kotlin in android development
Save time with kotlin in android developmentSave time with kotlin in android development
Save time with kotlin in android development
Adit Lal
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutines
NAVER Engineering
 
Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - Coroutine
Sean Tsai
 
KOTLIN COROUTINES - PART 1
KOTLIN COROUTINES - PART 1KOTLIN COROUTINES - PART 1
KOTLIN COROUTINES - PART 1
Bartosz Kozajda
 
What’s new in Kotlin?
What’s new in Kotlin?What’s new in Kotlin?
What’s new in Kotlin?
Squareboat
 
Having Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo SurabayaHaving Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo Surabaya
DILo Surabaya
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
Thierry Wasylczenko
 
Android Jetpack + Coroutines: To infinity and beyond
Android Jetpack + Coroutines: To infinity and beyondAndroid Jetpack + Coroutines: To infinity and beyond
Android Jetpack + Coroutines: To infinity and beyond
Ramon Ribeiro Rabello
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRready
MobileAcademy
 
Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016
Danny Preussler
 

Similar a droidcon Transylvania - Kotlin Coroutines (20)

Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
Kotlin Generation
Kotlin GenerationKotlin Generation
Kotlin Generation
 
Building Mobile Apps with Android
Building Mobile Apps with AndroidBuilding Mobile Apps with Android
Building Mobile Apps with Android
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
 
Kotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutinesKotlin from-scratch 3 - coroutines
Kotlin from-scratch 3 - coroutines
 
Practical tips for building apps with kotlin
Practical tips for building apps with kotlinPractical tips for building apps with kotlin
Practical tips for building apps with kotlin
 
Coroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in PractiseCoroutines for Kotlin Multiplatform in Practise
Coroutines for Kotlin Multiplatform in Practise
 
Performance #6 threading
Performance #6  threadingPerformance #6  threading
Performance #6 threading
 
Save time with kotlin in android development
Save time with kotlin in android developmentSave time with kotlin in android development
Save time with kotlin in android development
 
Introduction to kotlin coroutines
Introduction to kotlin coroutinesIntroduction to kotlin coroutines
Introduction to kotlin coroutines
 
Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - Coroutine
 
KOTLIN COROUTINES - PART 1
KOTLIN COROUTINES - PART 1KOTLIN COROUTINES - PART 1
KOTLIN COROUTINES - PART 1
 
What’s new in Kotlin?
What’s new in Kotlin?What’s new in Kotlin?
What’s new in Kotlin?
 
Having Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo SurabayaHaving Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo Surabaya
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Android Jetpack + Coroutines: To infinity and beyond
Android Jetpack + Coroutines: To infinity and beyondAndroid Jetpack + Coroutines: To infinity and beyond
Android Jetpack + Coroutines: To infinity and beyond
 
Kotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRreadyKotlin for Android - Vali Iorgu - mRready
Kotlin for Android - Vali Iorgu - mRready
 
Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016Unit testing without Robolectric, Droidcon Berlin 2016
Unit testing without Robolectric, Droidcon Berlin 2016
 

Último

Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Envertis Software Solutions
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
Peter Muessig
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
SOCRadar
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
Marcin Chrost
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
Patrick Weigel
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
Bert Jan Schrijver
 
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfTop Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
VALiNTRY360
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
Hornet Dynamics
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Julian Hyde
 
Mobile app Development Services | Drona Infotech
Mobile app Development Services  | Drona InfotechMobile app Development Services  | Drona Infotech
Mobile app Development Services | Drona Infotech
Drona Infotech
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 

Último (20)

Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
socradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdfsocradar-q1-2024-aviation-industry-report.pdf
socradar-q1-2024-aviation-industry-report.pdf
 
Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !Enums On Steroids - let's look at sealed classes !
Enums On Steroids - let's look at sealed classes !
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
WWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders AustinWWDC 2024 Keynote Review: For CocoaCoders Austin
WWDC 2024 Keynote Review: For CocoaCoders Austin
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
J-Spring 2024 - Going serverless with Quarkus, GraalVM native images and AWS ...
 
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfTop Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
 
Mobile app Development Services | Drona Infotech
Mobile app Development Services  | Drona InfotechMobile app Development Services  | Drona Infotech
Mobile app Development Services | Drona Infotech
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 

droidcon Transylvania - Kotlin Coroutines

  • 1. Kotlin Coroutines: Multi-threading made easy Arthur Nagy Halcyon Mobile
  • 2. Agenda 1. What are coroutines 2. Coroutines in Android 3. Why use coroutines
  • 3. What are coroutines “coroutines are computations that can be suspended without blocking a thread.” ● Not a new concept, introduced in the `60s ● Adopted by multiple programming languages ● Coroutines in Kotlin: ○ minimal low-level APIs in its standard library ○ kotlinx.coroutines libraries
  • 4. What are coroutines ● Terminology : ○ Coroutine ○ Suspending function ○ Coroutine builder ○ Continuation ○ Coroutine context
  • 5. Coroutine ● An instance of suspendable computation ● Similar to a thread (light-weight thread) ● Also similar to a future or promise
  • 6. Suspending functions ● Functions which suspend a coroutine execution ● suspend keyword ● Suspending functions can be used: ○ Inside other functions marked with the suspend keyword ○ Inside a coroutine ● suspendCoroutine ○ Bridge between coroutine suspension and callback world
  • 7. Suspending functions /** * Obtains the current continuation instance * inside suspend functions and suspends * currently running coroutine. */ suspend inline fun <T> suspendCoroutine( crossinline block: (Continuation<T>) -> Unit): T =
  • 8. Suspending functions public interface Continuation<in T> { public val context: CoroutineContext public fun resume(value: T) public fun resumeWithException(exception: Throwable) }
  • 9. Suspending functions suspend fun firstFun(): ResultType = suspendCoroutine { continuation -> // do some heavy work // resume the coroutine continuation with a result: continuation.resume(result) // or if there was an error: continuation.resumeWithException(exception) }
  • 10. Coroutine builders ● Functions which start a coroutine ● Bridge between non-coroutine & coroutine world ● Most common coroutine builders: ○ launch ○ async ○ withContext
  • 11. Coroutine builders launch { // everything inside happens on // a background thread pool } // continue app operations
  • 12. Coroutine builders fun launch( context: CoroutineContext = Dispatchers.Default, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job
  • 13. Coroutine builders val result: Deferred<T> = async { // do stuff on the background thread // which returns a value T when done } result.await()
  • 14. Coroutine builders val result: T = withContext(BACKGROUND) { // do stuff on the background thread // which returns a value T when done }
  • 16. Coroutines in Android kotlin { experimental { coroutines 'enable' } } dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.25.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.25.0' }
  • 17. class BlurActivity : AppCompatActivity() { ... override fun onActivityResult(requestC: Int, resultC: Int, data: Intent?) { val imageUri = data?.data launch(UI) { val resultImage = withContext(BACKGROUND) { blurImage(imageUri) } viewBinding.image.setImageURI(resultImage) viewModel.uploadImage(resultImage) } } ... }
  • 18. suspend fun blurImage(imageUri: Uri): Uri = suspendCoroutine { continuation -> try { val imageBitmap = getBitmapFromImageUri(imageUri) val blurredImage = applyBlurOnBitmap(imageBitmap) val blurredImageFile = saveBitmapToTemporaryFile(blurredImage) continuation.resume(blurredImageFile) } catch (e: Exception) { continuation.resumeWithException(e) } }
  • 19. class BlurActivity : AppCompatActivity() { ... override fun onActivityResult(requestC: Int, resultC: Int, data: Intent?) { val imageUri = data?.data launch(UI) { val resultImage = withContext(BACKGROUND) { blurImage(imageUri) } viewBinding.image.setImageURI(resultImage) viewModel.uploadImage(resultImage) } } ... }
  • 20. class BlurViewModel( private val restApiService: RestApiService ) : ViewModel() { ... fun uploadImage(imageUri: Uri) { // update UI state, i.e: show progress, etc launch(BACKGROUND) { val imageFile = File(imageUri.path) val imageFilePart = createImagePart(imageFile) val response = restApiService.uploadBlurredImage(imageFilePart).await() // use our response to update UI state, etc. } } ... }
  • 21. restApiService.uploadBlurredImage(imageFilePart).enqueue(Callback<> { override fun onResponse(call, response) { if (response.isSuccessful){ val blurResponse = response.body()!! // use our response to update UI state, etc. } } override fun onFailure(call, throwable) { } })
  • 22. launch(BACKGROUND) { val response = restApiService.uploadBlurredImage(imageFilePart).await() }
  • 23. interface RestApiService { @Multipart @POST("/blurred_image") fun uploadBlurredImage(@Part file: Part): Call<BlurResponse> }
  • 24. suspend fun <T> Call<T>.await(): T = suspendCoroutine { continuation -> enqueue(object: Callback<T> { override fun onResponse(call: Call<T>, response: Response<T>) { if (response.isSuccessful) { continuation.resume(response.body()!!) } else { continuation.resumeWithException(RequestException(response.message())) } } override fun onFailure(call: Call<T>, t: Throwable) { continuation.resumeWithException(t) } }) }
  • 25. What about Android lifecycle handling & cancelation?
  • 26. class BlurActivity : AppCompatActivity() { ... launch(UI) { val resultImage = withContext(BACKGROUND) { blurImage(imageUri) } } ... }
  • 27. class BlurActivity : AppCompatActivity() { ... val job = launch(UI) { val resultImage = withContext(BACKGROUND) { blurImage(imageUri) } } ... override fun onStop() { super.onStop() job.cancel() } }
  • 28. class CoroutineLifecycleObserver : LifecycleObserver { var parentJob: Job = Job() @OnLifecycleEvent(Lifecycle.Event.ON_START) fun start() { if (parentJob.isCompleted) { parentJob = Job() } } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun cancel() { if (parentJob.isActive) { parentJob.cancel() } } } gist.github.com/chrisbanes/152d325211401843326068c24e0d11b1
  • 29. class BlurActivity : AppCompatActivity() { private val coroutineObserver = CoroutineLifecycleObserver() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... lifecycle.addObserver(coroutineObserver) } launch(context = UI, parent = coroutineObserver.job) { val resultImage = withContext(BACKGROUND) { blurImage(imageUri) } } }
  • 30. open class CoroutineViewModel : ViewModel() { private val parentJob = Job() override fun onCleared() { super.onCleared() parentJob.cancel() } protected fun launchWithParent( context: CoroutineContext = BACKGROUND, block: suspend CoroutineScope.() -> Unit ) = launch(context = context, parent = parentJob, block = block) }
  • 31. class BlurViewModel( private val restApiService: RestApiService ) : CoroutineViewModel() { fun uploadImage(imageUri: Uri) { launchWithParent(BACKGROUND) { ... } } }
  • 32. Why use coroutines ● Asynchronous code sequentially ● No more callback-hell
  • 33. asyncOperation(object: Callback { fun onSuccess(result) { anotherOne(result, object: Callback { fun onSuccess(secondResult){ lastOne(secondResult, object: Callback { fun onSuccess(thirdResult){ useResult(thirdResult) } fun onError(exception){ handleError(exception) } }) } fun onError(exception){ handleError(exception) } }) } fun onError(exception) { handleError(exception) } })
  • 34. Why use coroutines ● Asynchronous code sequentially ● No more callback-hell ● “It’s experimental, we can’t use it!” ● “We already have so many options, why use this one?!”
  • 35. Why use coroutines val blurAsyncTask = object : AsyncTask<Uri, Int, Uri>() { override fun doInBackground(vararg params: Uri?): Uri { return blurImage(params) } override fun onPostExecute(result: Uri?) { viewBinding.image.setImageURI(result) viewModel.uploadImage(result) } } blurAsyncTask.execute(imageUri)
  • 36. Why use coroutines private val executors = Executors.newCachedThreadPool() fun uploadImage(imageUri: Uri) { executors.execute { val imageFile = File(imageUri.path) val imageFilePart = createImagePart(imageFile) restApiService.uploadBlurredImage(imageFilePart).enqueue(Callback<> { override fun onResponse(response: Response<>) { // use the response to update state, etc. } override fun onFailure(t: Throwable) { } }) } }
  • 37. Why use coroutines disposables.add(Single .fromCallable { blurImage(imageUri) } .subscribeOn(Schedulers.computation()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ resultImage -> viewBinding.image.setImageURI(resultImage) viewModel.uploadImage(resultImage) },{ error -> }) )
  • 38. Why use coroutines fun uploadImage(imageUri: Uri) { disposables.add(Single.fromCallable { val imageFile = File(imageUri.path) createImagePart(imageFile) }.flatMap(restApiService::uploadBlurredImage) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ blurResponse -> //update UI state, etc. }, { error -> }) ) }
  • 39. ● There’s a lot more: ○ Exception handling, channels, actors, etc. ● Resources: ○ kotlinlang.org/docs/reference/coroutines.html ○ github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-infor mal.md ○ github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md ○ gist.github.com/chrisbanes/152d325211401843326068c24e0d11b1 ○ github.com/gildor/kotlin-coroutines-retrofit
  • 40. Thank you! ● twitter.com/android_halcyon ● medium.com/halcyon-mobile ● halcyonmobile.com ● arthurnagy.me