SlideShare a Scribd company logo
KOTLIN COROUTINES AND ANDROID
SITTING IN A TREE...
KAI KOENIG (@AGENTK)
#droidconVN
HELLO
HELLO
My name is Kai!
Software Architect in the web and mobile (Android) space ‹
from New Zealand.
Stuff I enjoy: Android, Kotlin, CFML, compilers and parsers, aviation and ïŹ‚ying
small aircraft, cats and chickens, Nintendo video games of all ages!
Follow me on Twitter: @AgentK
#droidconVN
AGENDA
AGENDA
▾ Kotlin in 3 minutes
▾ Why coroutines?
▾ Using coroutines in your Kotlin code
▾ Libraries and coroutines on Android
KOTLIN IN 3 MINUTES
https://www.ïŹ‚ickr.com/photos/tschiae/8080742303/
#droidconVN
HISTORY OF KOTLIN (I)
▾ Jetbrains wanted a more efïŹcient JVM language when building products
▾ Looked at Scala, Groovy, etc. but came up with their own language spec
▾ First shown at the JVM Language Summit in 2011
▾ Got some traction in Android-land in 2014
▾ Modern language features (lambdas, HOF etc) but Java 6 byte code
▾ Low methods count (~7000)
▾ Strong focus on concision and an efïŹcient, bloat-free language
KOTLIN IN 3 MINUTES
#droidconVN
HISTORY OF KOTLIN (II)
▾ Since 1.0 release in early 2016:
▾ multiple maintenance releases
▾ now at 1.0.7
▾ 1.1 was released in Feb 2017,
▾ currently at 1.1.60
▾ experimental new feature: Kotlin coroutines
KOTLIN IN 3 MINUTES
#droidconVN
HISTORY OF KOTLIN (III)
▾ At Google IO 2017, Kotlin became a ïŹrst-grade language for Android
▾ Release of 1.2 happened in late 2017 (CHECK)
▾ Java 9 compatibility
▾ Multiplatform projects
▾ Huge improvements to StdLib, type inference, smart cast etc.
▾ Strong community, lots of interesting frameworks, awesome support from
Jetbrains
KOTLIN IN 3 MINUTES
#droidconVN
KOTLIN IN 5 MINUTES
PROMINENT LANGUAGE FEATURES
▾ Immutability
▾ String templates
▾ Explicit null handling
▾ Properties and Fields
▾ Data classes
▾ Extension functions
▾ Syntactic sugar
▾ Type inference
▾ Lambdas
▾ Collection API
▾ Type-safe builders
▾ Java-Kotlin-Interop
WHY COROUTINES?
https://www.ïŹ‚ickr.com/photos/61299367@N05/9448165205
#droidconVN
WHY COROUTINES?
MOTIVATION
▾ Asynchronous programming is becoming increasingly important
▾ Problem: the need to avoid blocking introduces a lot of complexity
▾ Threads are:
▾ expensive to manage and limited
▾ complex in applications with lots of mutable state
▾ usually even more complex to deal with in UI-driven applications
▾ Callback hell (very common in Javascript)
#droidconVNhttp://slides.com/michaelholroyd/asyncnodejs/#/
#droidconVN
WHY COROUTINES?
HISTORY
▾ Coroutines were ïŹrst mentioned and used in Simula 67
▾ detach & resume keywords to suspend and then later resume execution
▾ Pushed aside by industry trend towards multi-threading
▾ C# has async/await (language-level keywords)
▾ Go was one of the ïŹrst modern languages re-introducing coroutines
#droidconVN
WHY COROUTINES?
COROUTINES IN KOTLIN (I)
▾ Kotlin’s approach: Suspending functions
▾ Function/lambda that can be suspended and resumed
▾ Requires no context-switching on the OS level
▾ Minimal integration into the core language and stdlib, most of functionality
provided by libraries
▾ Design allows for a variety of asynchronous API methodologies to be
implemented on top of Kotlin coroutines
▾ Supposed to feel like writing traditional code
#droidconVN
WHY COROUTINES?
COROUTINES IN KOTLIN (II)
▾ Easiest way to think about a coroutine is a very light-weighted thread
▾ They can run in parallel
▾ Coroutines can wait for each other
▾ They can communicate with each other
▾ Very, very cheap to create (compared to threads)
▾ A thread can run a lot of coroutines
#droidconVN
WHY COROUTINES?
COROUTINES IN KOTLIN (III)
▾ Multiple layers of libraries and integration points:
▾ Language support: suspending functions
▾ Low-level library & generators in kotlin.coroutines
▾ Mid-level library in kotlinx.coroutines
▾ High-level libraries (Anko etc.)
USING COROUTINES IN
YOUR KOTLIN CODE
https://www.ïŹ‚ickr.com/photos/97114911@N05/14720054418
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
FUNDAMENTALS
▾ Kotlin 1.1.4 is the absolute minimum, better 1.1.50+ or right away latest 1.2
▾ Enable experimental feature in Gradle
kotlin {
experimental {
coroutines 'enable'
}
}
compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5'
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
“HELLO WORLD”
▾ launch {
} starts new coroutine on CommonPool thread pool
▾ delay() is a suspending function (not blocking a thread)
fun main(args: Array<String>) {
println("Start on main thread")
launch(CommonPool) {
delay(5000)
println("Hello from coroutine")
}
println("Hello from main thread")
Thread.sleep(10000)
println("Stop on main thread")
}
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
“HELLO WORLD” IN BETTER
▾ Wait for the coroutines to ïŹnish - launch {
} returns a Job object
fun main(args: Array<String>) = runBlocking {
println("Start on main thread")
val job = launch(CommonPool) {
delay(5000)
println("Hello from coroutine")
}
println("Hello from main thread")
job.join()
println("Stop on main thread")
}
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
THREADS VS COROUTINES
fun main(args: Array<String>) {
val jobs = List(10_000) {
thread(start = true) {
Thread.sleep(1000L)
print(".")
}
}
jobs.forEach { it.join() }
}
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
THREADS VS COROUTINES
fun main(args: Array<String>) = runBlocking<Unit> {
val jobs = List(10_000) {
launch(CommonPool) {
delay(1000L)
print(".")
}
}
jobs.forEach { it.join() }
}
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
ASYNC/AWAIT (I)
▾ async {
} starts new coroutine and returns a Deferred<T> object
▾ Deferred<T>.await() returns result of the coroutine
▾ await() needs to be called from inside a coroutine, because it needs to suspend
in a non-blocking way
▾ Solution: wrap into runBlocking {
} coroutine
▾ Starts coroutine and wait until it’s ïŹnished
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
ASYNC/AWAIT (II)
fun main(args: Array<String>) {
val deferred = (1..60_000).map { n ->
async (CommonPool) {
n
}
}
runBlocking {
val sum = deferred.sumBy { it.await() }
println("Sum: $sum")
}
}
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
SUSPEND FUNCTIONS (I)
▾ Coroutines can suspend without blocking a thread
▾ Functions that might suspend need to be marked with the suspend keyword
▾ They can only be called from another suspend function or a coroutine
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
SUSPEND FUNCTIONS (II)
fun main(args: Array<String>) {
val deferred = (1..1_000_000).map { n ->
async (CommonPool) {
doWork(n)
}
}
runBlocking {
...
}
}
suspend fun doWork(n: Int) : Int {
delay(50)
return n
}
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
BEHIND THE SCENES
▾ Kotlin coroutines are very light on language features:
▾ suspend the only new keyword added to the language and acts pretty much
like a compiler ïŹ‚ag
▾ Continuation and CoroutineContext in stdlib
▾ All the rest is in the kotlinx.coroutines library
This makes the design of Kotlin coroutines very composable.
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
MORE BEHIND THE SCENES
▾ At compilation:
▾ Suspending functions compile to functions with a general callback interface
of type Continuation
▾ Code with suspension points compiles to a state machine
▾ launch, runBlocking, async etc. are often called coroutine builders
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
LAUNCH VS ASYNC
▾ Conceptually very similar
▾ launch {
} returns a Job, no resulting value
▾ async {
} returns a Deferred - a future that can be used to obtain a value
▾ async generally suited better in situations with independent concurrent ïŹ‚ows
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
WAITING AND CANCELLING
▾ cancel() and then join() can be used to terminate a coroutine execution early
▾ Job has an extension function cancelAndJoin() doing both at once
val job = launch {
repeat(1000) { i ->
println("job: I'm sitting here and delaying $i ...")
delay(500L)
}
}
delay(1300L)
println("main: I'm really over waiting!")
job.cancel()
job.join() // or use: job.cancelAndJoin()
println("main: Let's go.")
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
DEALING WITH TIMEOUTS
▾ Quite often the motivation for cancelling is a timeout:
▾ Track yourself via the Job instance
▾ Use withTimeout() {
}
withTimeout(1300L) {
repeat(1000) { i ->
println("I'm waiting $i ...")
delay(500L)
}
}
#droidconVN
USING COROUTINES IN YOUR KOTLIN CODE
THAT’S NOT ALL OF IT YET
▾ Coroutine contexts
▾ Coroutines and threads
▾ Channels
▾ Pipelines
▾ Dealing with state
▾ Shared (mutable) state & Actors
Compare Coroutines with Java Futures API
LIBRARIES AND
COROUTINES ON
ANDROID
https://www.ïŹ‚ickr.com/photos/qiaomeng/4665885561/
#droidconVN
MOTIVATION
▾ In general, UI-driven apps need to be aware of long-running processes
▾ Android speciïŹcally:
▾ we can’t do any networking on the UI thread
▾ we need to avoid long-running operations due to ANRs
▾ The kotlinx.coroutines library by Jetbrains provides a starting point for
Android, too.
LIBRARIES AND COROUTINES ON ANDROID
compile 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.22.5'
#droidconVN
UI CONTEXT
▾ The Android library provides access to a coroutine context for the UI thread
▾ Coroutine launches in UI thread, UI updates and suspending functions are
possible
▾ Non-blocking, UI is not frozen
LIBRARIES AND COROUTINES ON ANDROID
launch(UI) {
for (i in 10 downTo 1) {
hello.text = "Countdown $i ..."
delay(500)
}
hello.text = "Done!"
}
#droidconVN
OTHER UI THREAD CONCERNS
▾ For Jobs and cancelling coroutines, the same general principles still apply
▾ using launch {
} provides a reference to a Job
▾ can be cancelled with cancel() - for instance via UI control
▾ In UI scenarios useful to write own coroutines builders as extension functions
LIBRARIES AND COROUTINES ON ANDROID
button.onClick {
...
}
fun View.onClick(action: suspend () -> Unit) {
setOnClickListener {
launch(UI) {
action()
}
}
}
#droidconVN
OTHER UI THREAD CONCERNS
▾ Interesting topics for further study:
▾ Limit and manage coroutines via actors
▾ Dealing with event conïŹ‚ation
▾ Channel.CONFLATED
▾ Channel.UNLIMITED
LIBRARIES AND COROUTINES ON ANDROID
#droidconVN
THREAD BLOCKING OPERATIONS AND THE UI
▾ CPU-intensive computations and/or API calls
▾ Can’t be done from UI thread or UI thread-conïŹned coroutine
▾ Solution: suspending functions with execution context CommonPool
LIBRARIES AND COROUTINES ON ANDROID
suspend fun fib(x: Int): Int = run(CommonPool) {
fibBlocking(x)
}
fun fibBlocking(x: Int): Int =
if (x <= 1) 1 else fibBlocking(x - 1) + fibBlocking(x - 2)
#droidconVN
NETWORK CALLS (I)
▾ Callback-free API call, handle ofïŹ‚ine-exceptions
LIBRARIES AND COROUTINES ON ANDROID
fun getUsers() : Deferred<List<Users>> {
return async(CommonPool) {
val request = Request.Builder().url(<SOMEURL>).build()
val response = OkHttpClient().newCall(request).execute()
// parse response...
}
}
#droidconVN
NETWORK CALLS (II)
▾ Handle exceptions in calling code
▾ Use result object’s await() to obtain the data (suspending the coroutine)
▾ Use launch {
} builder to trigger execution of getUsers
LIBRARIES AND COROUTINES ON ANDROID
launch(UI) {
try {
val result = getUsers()
adapter.setElements(result.await())
...
} catch (exception: IOException){
// we’re offline
}
#droidconVN
ANKO
▾ More often than not identiïŹed with declarative UI for Android/Kotlin
▾ But it also has APIs for:
▾ Async
▾ SQLite
▾ Anko 0.9 introduced naming changes around the Async API
▾ Since Anko 0.10, Anko has support for coroutines
LIBRARIES AND COROUTINES ON ANDROID
#droidconVN
LIBRARIES AND COROUTINES ON ANDROID
COROUTINES IN ANKO
▾ Add anko-coroutines dependency
▾ Earlier versions of Anko already had support for async handling
▾ New:
▾ Coroutines in listeners
▾ bg()
▾ asReference()
fun getData(): Data { ... }
fun showData(data: Data) { ... }
async(UI) {
val data: Deferred<Data> = bg {
// Runs on the background
getData()
}
// This code is executed on the UI thread
showData(data.await())
}
#droidconVN
LIBRARIES AND COROUTINES ON ANDROID
COROUTINES WITH ASYNCAWAIT
▾ Async/await approach
▾ Very rich library on top of Kotlin’s
coroutine core
▾ Plugins for RetroïŹt and rxJava
async {
val result = await {
//Long running code
}
// Use result
}
async {
val repos = await { github.getRepos() }
showList(repos)
repos.forEach { repo ->
val stats = await { github.getStats
(repo.name) }
showStats(repo, stats)
}
}
#droidconVN
LIBRARIES AND COROUTINES ON ANDROID
COROUTINES AND RXJAVA (I)
▾ There is an interop library for RX2 with coroutines: org.jetbrains.kotlinx:kotlinx-
coroutines-rx2
▾ rxJava -> coroutines: openSubscription(), awaitFirstOrDefault()
▾ coroutines -> rxJava:
▾ Job.asCompletable, Deferred.asSingle()
▾ Multiple coroutine builders: rxMaybe, rxCompletable etc.
#droidconVN
LIBRARIES AND COROUTINES ON ANDROID
COROUTINES AND RXJAVA (II)
▾ Method count:
▾ Coroutines ~10-20% less than rxJava
▾ APK size:
▾ Similar, ~10-20% smaller than with rxJava
▾ Interop libraries add quite a lot to method count and APK size.
OTHER THINGS AND
FINAL THOUGHTS
https://www.ïŹ‚ickr.com/photos/chrispiascik/4054331891
#droidconVN
OTHER THINGS & FINAL THOUGHTS
UNIT TESTING SUSPENDING FUNCTIONS
▾ They need a coroutine to run, easiest way seems to be with runBlocking {
}
import kotlinx.coroutines.experimental.runBlocking
import org.testng.annotations.Test
class MyTest {
@Test
fun testMySuspendingFunction() = runBlocking<Unit> {
// your test code here
}
}
#droidconVN
OTHER THINGS & FINAL THOUGHTS
EXPERIMENTAL?
▾ Coroutines are currently experimental in Kotlin 1.x, however:
▾ Very sound approach of dealing with concurrency
▾ Jetbrains guarantees backwards compatibility
▾ Potentially no forward compatibility
▾ Coroutines can and should be used in production
▾ Quite low learning curve compared to rxJava and other libraries
#droidconVN
OTHER THINGS
RESOURCES
▾ Introduction to background processing in Android:‹
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
▾ Coroutines design document:‹
https://github.com/Kotlin/kotlin-coroutines
▾ Coroutines guide:‹
https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md
▾ Java Futures & Coroutines:‹
https://blog.frankel.ch/concurrency-java-futures-kotlin-coroutines/#gsc.tab=0
▾ Anko: ‹
https://github.com/Kotlin/anko
▾ AsyncAwait:‹
https://github.com/metalabdesign/AsyncAwait
▾ Coroutines and reactive streams:‹
https://github.com/Kotlin/kotlinx.coroutines/blob/master/reactive/README.md
#droidconVN
OTHER THINGS
GET IN TOUCH
Kai Koenig
Email: kai@ventego-creative.co.nz
Work: http://www.ventego-creative.co.nz
Twitter: @AgentK
Telegram: @kaikoenig
Slides: http://www.slideshare.com/agentk

More Related Content

What's hot (20)

PDF
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Codemotion
 
PPTX
ToyoTech_LT : C#.NET
Naoki Ikeguchi
 
PDF
Types - slice, map, new, make, struct - Gopherlabs
sangam biradar
 
PDF
Understanding how concurrency work in os
GenchiLu1
 
PDF
Extensible web
Jxck Jxck
 
ODP
Developing high-performance network servers in Lisp
Vladimir Sedach
 
PDF
OSDC 2017 - Casey Callendrello -The evolution of the Container Network Interface
NETWAYS
 
PDF
Chromium: NaCl and Pepper API
Chang W. Doh
 
PPTX
Deep dive - Concourse CI/CD and Pipelines
Syed Imam
 
PDF
Groovy a Scripting Language for Java
Charles Anderson
 
PDF
The Parenscript Common Lisp to JavaScript compiler
Vladimir Sedach
 
PDF
How we do python
Brice Laurencin
 
KEY
Distributed app development with nodejs and zeromq
Ruben Tan
 
PPT
Javaone2008 Bof 5101 Groovytesting
Andres Almiray
 
PPTX
Go Is Your Next Language — Sergii Shapoval
GlobalLogic Ukraine
 
PPTX
Rethinking React
GlobalLogic Ukraine
 
ODP
Rust Primer
Knoldus Inc.
 
PPT
Leveraging zeromq for node.js
Ruben Tan
 
PDF
Import golang; struct microservice
Giulio De Donato
 
PPTX
GWT videocall: power-up your mobile & web app with WebRTC
GWTcon
 
Asynchronous IO in Rust - Enrico Risa - Codemotion Rome 2017
Codemotion
 
ToyoTech_LT : C#.NET
Naoki Ikeguchi
 
Types - slice, map, new, make, struct - Gopherlabs
sangam biradar
 
Understanding how concurrency work in os
GenchiLu1
 
Extensible web
Jxck Jxck
 
Developing high-performance network servers in Lisp
Vladimir Sedach
 
OSDC 2017 - Casey Callendrello -The evolution of the Container Network Interface
NETWAYS
 
Chromium: NaCl and Pepper API
Chang W. Doh
 
Deep dive - Concourse CI/CD and Pipelines
Syed Imam
 
Groovy a Scripting Language for Java
Charles Anderson
 
The Parenscript Common Lisp to JavaScript compiler
Vladimir Sedach
 
How we do python
Brice Laurencin
 
Distributed app development with nodejs and zeromq
Ruben Tan
 
Javaone2008 Bof 5101 Groovytesting
Andres Almiray
 
Go Is Your Next Language — Sergii Shapoval
GlobalLogic Ukraine
 
Rethinking React
GlobalLogic Ukraine
 
Rust Primer
Knoldus Inc.
 
Leveraging zeromq for node.js
Ruben Tan
 
Import golang; struct microservice
Giulio De Donato
 
GWT videocall: power-up your mobile & web app with WebRTC
GWTcon
 

Similar to Kotlin Coroutines and Android sitting in a tree - 2018 version (20)

PDF
Anko - The Ultimate Ninja of Kotlin Libraries?
Kai Koenig
 
PDF
Parallelizing CI using Docker Swarm-Mode
Akihiro Suda
 
PDF
2017: Kotlin - now more than ever
Kai Koenig
 
PDF
codemotion-docker-2014
Carlo Bonamico
 
PDF
Real-World Docker: 10 Things We've Learned
RightScale
 
PDF
Why everyone is excited about Docker (and you should too...) - Carlo Bonamic...
Codemotion
 
PDF
Docker Introduction.pdf
OKLABS
 
PDF
Improving app performance with Kotlin Coroutines
Hassan Abid
 
PPTX
Accelerate your development with Docker
Andrey Hristov
 
PDF
Accelerate your software development with Docker
Andrey Hristov
 
PDF
Why I ❀ Kotlin Multiplatform (and want YOU to also ❀ Kotlin Multiplatform)
Derek Lee
 
PDF
Bring Continuous Integration to Your Laptop With the Drone CI Docker Extensio...
jemije2490
 
PDF
Kotlin The Whole Damn Family
Garth Gilmour
 
PPTX
Architecting .NET Applications for Docker and Container Based Deployments
Ben Hall
 
PPTX
Powercoders · Docker · Fall 2021.pptx
IgnacioTamayo2
 
PDF
Coroutines for Kotlin Multiplatform in Practise
Christian Melchior
 
PDF
Perspectives on Docker
RightScale
 
PDF
The Future of Security and Productivity in Our Newly Remote World
DevOps.com
 
PDF
[HKOSCon x COSCUP 2020][20200801][Ansible: From VM to Kubernetes]
Wong Hoi Sing Edison
 
PDF
[KubeConEU] Building images efficiently and securely on Kubernetes with BuildKit
Akihiro Suda
 
Anko - The Ultimate Ninja of Kotlin Libraries?
Kai Koenig
 
Parallelizing CI using Docker Swarm-Mode
Akihiro Suda
 
2017: Kotlin - now more than ever
Kai Koenig
 
codemotion-docker-2014
Carlo Bonamico
 
Real-World Docker: 10 Things We've Learned
RightScale
 
Why everyone is excited about Docker (and you should too...) - Carlo Bonamic...
Codemotion
 
Docker Introduction.pdf
OKLABS
 
Improving app performance with Kotlin Coroutines
Hassan Abid
 
Accelerate your development with Docker
Andrey Hristov
 
Accelerate your software development with Docker
Andrey Hristov
 
Why I ❀ Kotlin Multiplatform (and want YOU to also ❀ Kotlin Multiplatform)
Derek Lee
 
Bring Continuous Integration to Your Laptop With the Drone CI Docker Extensio...
jemije2490
 
Kotlin The Whole Damn Family
Garth Gilmour
 
Architecting .NET Applications for Docker and Container Based Deployments
Ben Hall
 
Powercoders · Docker · Fall 2021.pptx
IgnacioTamayo2
 
Coroutines for Kotlin Multiplatform in Practise
Christian Melchior
 
Perspectives on Docker
RightScale
 
The Future of Security and Productivity in Our Newly Remote World
DevOps.com
 
[HKOSCon x COSCUP 2020][20200801][Ansible: From VM to Kubernetes]
Wong Hoi Sing Edison
 
[KubeConEU] Building images efficiently and securely on Kubernetes with BuildKit
Akihiro Suda
 
Ad

More from Kai Koenig (20)

PDF
Why a whole country skipped a day - Fun with Timezones
Kai Koenig
 
PDF
Android 103 - Firebase and Architecture Components
Kai Koenig
 
PDF
Android 102 - Flow, Layouts and other things
Kai Koenig
 
PDF
Android 101 - Building a simple app with Kotlin in 90 minutes
Kai Koenig
 
PDF
Improving your CFML code quality
Kai Koenig
 
PDF
Summer of Tech 2017 - Kotlin/Android bootcamp
Kai Koenig
 
PDF
Coding for Android on steroids with Kotlin
Kai Koenig
 
PDF
API management with Taffy and API Blueprint
Kai Koenig
 
PDF
Little Helpers for Android Development with Kotlin
Kai Koenig
 
PDF
Introduction to Data Mining
Kai Koenig
 
PDF
Garbage First and you
Kai Koenig
 
PDF
Real World Lessons in jQuery Mobile
Kai Koenig
 
PDF
The JVM is your friend
Kai Koenig
 
PDF
Regular Expressions 101
Kai Koenig
 
PDF
There's a time and a place
Kai Koenig
 
KEY
Clojure - an introduction (and some CFML)
Kai Koenig
 
KEY
AngularJS for designers and developers
Kai Koenig
 
KEY
Cryptography for developers
Kai Koenig
 
PDF
JVM and Garbage Collection Tuning
Kai Koenig
 
PDF
Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...
Kai Koenig
 
Why a whole country skipped a day - Fun with Timezones
Kai Koenig
 
Android 103 - Firebase and Architecture Components
Kai Koenig
 
Android 102 - Flow, Layouts and other things
Kai Koenig
 
Android 101 - Building a simple app with Kotlin in 90 minutes
Kai Koenig
 
Improving your CFML code quality
Kai Koenig
 
Summer of Tech 2017 - Kotlin/Android bootcamp
Kai Koenig
 
Coding for Android on steroids with Kotlin
Kai Koenig
 
API management with Taffy and API Blueprint
Kai Koenig
 
Little Helpers for Android Development with Kotlin
Kai Koenig
 
Introduction to Data Mining
Kai Koenig
 
Garbage First and you
Kai Koenig
 
Real World Lessons in jQuery Mobile
Kai Koenig
 
The JVM is your friend
Kai Koenig
 
Regular Expressions 101
Kai Koenig
 
There's a time and a place
Kai Koenig
 
Clojure - an introduction (and some CFML)
Kai Koenig
 
AngularJS for designers and developers
Kai Koenig
 
Cryptography for developers
Kai Koenig
 
JVM and Garbage Collection Tuning
Kai Koenig
 
Apps vs. Sites vs. Content - a vendor-agnostic view on building stuff for the...
Kai Koenig
 
Ad

Recently uploaded (20)

PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
PDF
Executive Business Intelligence Dashboards
vandeslie24
 
PDF
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PPTX
Engineering the Java Web Application (MVC)
abhishekoza1981
 
PDF
Salesforce CRM Services.VALiNTRY360
VALiNTRY360
 
PPTX
3uTools Full Crack Free Version Download [Latest] 2025
muhammadgurbazkhan
 
PPTX
Platform for Enterprise Solution - Java EE5
abhishekoza1981
 
PPTX
MailsDaddy Outlook OST to PST converter.pptx
abhishekdutt366
 
PDF
Unlock Efficiency with Insurance Policy Administration Systems
Insurance Tech Services
 
PPTX
Java Native Memory Leaks: The Hidden Villain Behind JVM Performance Issues
Tier1 app
 
PDF
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PPTX
MiniTool Power Data Recovery Full Crack Latest 2025
muhammadgurbazkhan
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
PDF
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
PPTX
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PDF
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
 
PPTX
Fundamentals_of_Microservices_Architecture.pptx
MuhammadUzair504018
 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
Executive Business Intelligence Dashboards
vandeslie24
 
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
Engineering the Java Web Application (MVC)
abhishekoza1981
 
Salesforce CRM Services.VALiNTRY360
VALiNTRY360
 
3uTools Full Crack Free Version Download [Latest] 2025
muhammadgurbazkhan
 
Platform for Enterprise Solution - Java EE5
abhishekoza1981
 
MailsDaddy Outlook OST to PST converter.pptx
abhishekdutt366
 
Unlock Efficiency with Insurance Policy Administration Systems
Insurance Tech Services
 
Java Native Memory Leaks: The Hidden Villain Behind JVM Performance Issues
Tier1 app
 
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
MiniTool Power Data Recovery Full Crack Latest 2025
muhammadgurbazkhan
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
Writing Better Code - Helping Developers make Decisions.pptx
Lorraine Steyn
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
 
Fundamentals_of_Microservices_Architecture.pptx
MuhammadUzair504018
 

Kotlin Coroutines and Android sitting in a tree - 2018 version

  • 1. KOTLIN COROUTINES AND ANDROID SITTING IN A TREE... KAI KOENIG (@AGENTK)
  • 2. #droidconVN HELLO HELLO My name is Kai! Software Architect in the web and mobile (Android) space ‹ from New Zealand. Stuff I enjoy: Android, Kotlin, CFML, compilers and parsers, aviation and ïŹ‚ying small aircraft, cats and chickens, Nintendo video games of all ages! Follow me on Twitter: @AgentK
  • 3. #droidconVN AGENDA AGENDA ▾ Kotlin in 3 minutes ▾ Why coroutines? ▾ Using coroutines in your Kotlin code ▾ Libraries and coroutines on Android
  • 4. KOTLIN IN 3 MINUTES https://www.ïŹ‚ickr.com/photos/tschiae/8080742303/
  • 5. #droidconVN HISTORY OF KOTLIN (I) ▾ Jetbrains wanted a more efïŹcient JVM language when building products ▾ Looked at Scala, Groovy, etc. but came up with their own language spec ▾ First shown at the JVM Language Summit in 2011 ▾ Got some traction in Android-land in 2014 ▾ Modern language features (lambdas, HOF etc) but Java 6 byte code ▾ Low methods count (~7000) ▾ Strong focus on concision and an efïŹcient, bloat-free language KOTLIN IN 3 MINUTES
  • 6. #droidconVN HISTORY OF KOTLIN (II) ▾ Since 1.0 release in early 2016: ▾ multiple maintenance releases ▾ now at 1.0.7 ▾ 1.1 was released in Feb 2017, ▾ currently at 1.1.60 ▾ experimental new feature: Kotlin coroutines KOTLIN IN 3 MINUTES
  • 7. #droidconVN HISTORY OF KOTLIN (III) ▾ At Google IO 2017, Kotlin became a ïŹrst-grade language for Android ▾ Release of 1.2 happened in late 2017 (CHECK) ▾ Java 9 compatibility ▾ Multiplatform projects ▾ Huge improvements to StdLib, type inference, smart cast etc. ▾ Strong community, lots of interesting frameworks, awesome support from Jetbrains KOTLIN IN 3 MINUTES
  • 8. #droidconVN KOTLIN IN 5 MINUTES PROMINENT LANGUAGE FEATURES ▾ Immutability ▾ String templates ▾ Explicit null handling ▾ Properties and Fields ▾ Data classes ▾ Extension functions ▾ Syntactic sugar ▾ Type inference ▾ Lambdas ▾ Collection API ▾ Type-safe builders ▾ Java-Kotlin-Interop
  • 10. #droidconVN WHY COROUTINES? MOTIVATION ▾ Asynchronous programming is becoming increasingly important ▾ Problem: the need to avoid blocking introduces a lot of complexity ▾ Threads are: ▾ expensive to manage and limited ▾ complex in applications with lots of mutable state ▾ usually even more complex to deal with in UI-driven applications ▾ Callback hell (very common in Javascript)
  • 12. #droidconVN WHY COROUTINES? HISTORY ▾ Coroutines were ïŹrst mentioned and used in Simula 67 ▾ detach & resume keywords to suspend and then later resume execution ▾ Pushed aside by industry trend towards multi-threading ▾ C# has async/await (language-level keywords) ▾ Go was one of the ïŹrst modern languages re-introducing coroutines
  • 13. #droidconVN WHY COROUTINES? COROUTINES IN KOTLIN (I) ▾ Kotlin’s approach: Suspending functions ▾ Function/lambda that can be suspended and resumed ▾ Requires no context-switching on the OS level ▾ Minimal integration into the core language and stdlib, most of functionality provided by libraries ▾ Design allows for a variety of asynchronous API methodologies to be implemented on top of Kotlin coroutines ▾ Supposed to feel like writing traditional code
  • 14. #droidconVN WHY COROUTINES? COROUTINES IN KOTLIN (II) ▾ Easiest way to think about a coroutine is a very light-weighted thread ▾ They can run in parallel ▾ Coroutines can wait for each other ▾ They can communicate with each other ▾ Very, very cheap to create (compared to threads) ▾ A thread can run a lot of coroutines
  • 15. #droidconVN WHY COROUTINES? COROUTINES IN KOTLIN (III) ▾ Multiple layers of libraries and integration points: ▾ Language support: suspending functions ▾ Low-level library & generators in kotlin.coroutines ▾ Mid-level library in kotlinx.coroutines ▾ High-level libraries (Anko etc.)
  • 16. USING COROUTINES IN YOUR KOTLIN CODE https://www.ïŹ‚ickr.com/photos/97114911@N05/14720054418
  • 17. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE FUNDAMENTALS ▾ Kotlin 1.1.4 is the absolute minimum, better 1.1.50+ or right away latest 1.2 ▾ Enable experimental feature in Gradle kotlin { experimental { coroutines 'enable' } } compile 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5'
  • 18. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE “HELLO WORLD” ▾ launch {
} starts new coroutine on CommonPool thread pool ▾ delay() is a suspending function (not blocking a thread) fun main(args: Array<String>) { println("Start on main thread") launch(CommonPool) { delay(5000) println("Hello from coroutine") } println("Hello from main thread") Thread.sleep(10000) println("Stop on main thread") }
  • 19. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE “HELLO WORLD” IN BETTER ▾ Wait for the coroutines to ïŹnish - launch {
} returns a Job object fun main(args: Array<String>) = runBlocking { println("Start on main thread") val job = launch(CommonPool) { delay(5000) println("Hello from coroutine") } println("Hello from main thread") job.join() println("Stop on main thread") }
  • 20. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE THREADS VS COROUTINES fun main(args: Array<String>) { val jobs = List(10_000) { thread(start = true) { Thread.sleep(1000L) print(".") } } jobs.forEach { it.join() } }
  • 21. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE THREADS VS COROUTINES fun main(args: Array<String>) = runBlocking<Unit> { val jobs = List(10_000) { launch(CommonPool) { delay(1000L) print(".") } } jobs.forEach { it.join() } }
  • 22. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE ASYNC/AWAIT (I) ▾ async {
} starts new coroutine and returns a Deferred<T> object ▾ Deferred<T>.await() returns result of the coroutine ▾ await() needs to be called from inside a coroutine, because it needs to suspend in a non-blocking way ▾ Solution: wrap into runBlocking {
} coroutine ▾ Starts coroutine and wait until it’s ïŹnished
  • 23. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE ASYNC/AWAIT (II) fun main(args: Array<String>) { val deferred = (1..60_000).map { n -> async (CommonPool) { n } } runBlocking { val sum = deferred.sumBy { it.await() } println("Sum: $sum") } }
  • 24. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE SUSPEND FUNCTIONS (I) ▾ Coroutines can suspend without blocking a thread ▾ Functions that might suspend need to be marked with the suspend keyword ▾ They can only be called from another suspend function or a coroutine
  • 25. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE SUSPEND FUNCTIONS (II) fun main(args: Array<String>) { val deferred = (1..1_000_000).map { n -> async (CommonPool) { doWork(n) } } runBlocking { ... } } suspend fun doWork(n: Int) : Int { delay(50) return n }
  • 26. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE BEHIND THE SCENES ▾ Kotlin coroutines are very light on language features: ▾ suspend the only new keyword added to the language and acts pretty much like a compiler ïŹ‚ag ▾ Continuation and CoroutineContext in stdlib ▾ All the rest is in the kotlinx.coroutines library This makes the design of Kotlin coroutines very composable.
  • 27. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE MORE BEHIND THE SCENES ▾ At compilation: ▾ Suspending functions compile to functions with a general callback interface of type Continuation ▾ Code with suspension points compiles to a state machine ▾ launch, runBlocking, async etc. are often called coroutine builders
  • 28. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE LAUNCH VS ASYNC ▾ Conceptually very similar ▾ launch {
} returns a Job, no resulting value ▾ async {
} returns a Deferred - a future that can be used to obtain a value ▾ async generally suited better in situations with independent concurrent ïŹ‚ows
  • 29. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE WAITING AND CANCELLING ▾ cancel() and then join() can be used to terminate a coroutine execution early ▾ Job has an extension function cancelAndJoin() doing both at once val job = launch { repeat(1000) { i -> println("job: I'm sitting here and delaying $i ...") delay(500L) } } delay(1300L) println("main: I'm really over waiting!") job.cancel() job.join() // or use: job.cancelAndJoin() println("main: Let's go.")
  • 30. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE DEALING WITH TIMEOUTS ▾ Quite often the motivation for cancelling is a timeout: ▾ Track yourself via the Job instance ▾ Use withTimeout() {
} withTimeout(1300L) { repeat(1000) { i -> println("I'm waiting $i ...") delay(500L) } }
  • 31. #droidconVN USING COROUTINES IN YOUR KOTLIN CODE THAT’S NOT ALL OF IT YET ▾ Coroutine contexts ▾ Coroutines and threads ▾ Channels ▾ Pipelines ▾ Dealing with state ▾ Shared (mutable) state & Actors Compare Coroutines with Java Futures API
  • 33. #droidconVN MOTIVATION ▾ In general, UI-driven apps need to be aware of long-running processes ▾ Android speciïŹcally: ▾ we can’t do any networking on the UI thread ▾ we need to avoid long-running operations due to ANRs ▾ The kotlinx.coroutines library by Jetbrains provides a starting point for Android, too. LIBRARIES AND COROUTINES ON ANDROID compile 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.22.5'
  • 34. #droidconVN UI CONTEXT ▾ The Android library provides access to a coroutine context for the UI thread ▾ Coroutine launches in UI thread, UI updates and suspending functions are possible ▾ Non-blocking, UI is not frozen LIBRARIES AND COROUTINES ON ANDROID launch(UI) { for (i in 10 downTo 1) { hello.text = "Countdown $i ..." delay(500) } hello.text = "Done!" }
  • 35. #droidconVN OTHER UI THREAD CONCERNS ▾ For Jobs and cancelling coroutines, the same general principles still apply ▾ using launch {
} provides a reference to a Job ▾ can be cancelled with cancel() - for instance via UI control ▾ In UI scenarios useful to write own coroutines builders as extension functions LIBRARIES AND COROUTINES ON ANDROID button.onClick { ... } fun View.onClick(action: suspend () -> Unit) { setOnClickListener { launch(UI) { action() } } }
  • 36. #droidconVN OTHER UI THREAD CONCERNS ▾ Interesting topics for further study: ▾ Limit and manage coroutines via actors ▾ Dealing with event conïŹ‚ation ▾ Channel.CONFLATED ▾ Channel.UNLIMITED LIBRARIES AND COROUTINES ON ANDROID
  • 37. #droidconVN THREAD BLOCKING OPERATIONS AND THE UI ▾ CPU-intensive computations and/or API calls ▾ Can’t be done from UI thread or UI thread-conïŹned coroutine ▾ Solution: suspending functions with execution context CommonPool LIBRARIES AND COROUTINES ON ANDROID suspend fun fib(x: Int): Int = run(CommonPool) { fibBlocking(x) } fun fibBlocking(x: Int): Int = if (x <= 1) 1 else fibBlocking(x - 1) + fibBlocking(x - 2)
  • 38. #droidconVN NETWORK CALLS (I) ▾ Callback-free API call, handle ofïŹ‚ine-exceptions LIBRARIES AND COROUTINES ON ANDROID fun getUsers() : Deferred<List<Users>> { return async(CommonPool) { val request = Request.Builder().url(<SOMEURL>).build() val response = OkHttpClient().newCall(request).execute() // parse response... } }
  • 39. #droidconVN NETWORK CALLS (II) ▾ Handle exceptions in calling code ▾ Use result object’s await() to obtain the data (suspending the coroutine) ▾ Use launch {
} builder to trigger execution of getUsers LIBRARIES AND COROUTINES ON ANDROID launch(UI) { try { val result = getUsers() adapter.setElements(result.await()) ... } catch (exception: IOException){ // we’re offline }
  • 40. #droidconVN ANKO ▾ More often than not identiïŹed with declarative UI for Android/Kotlin ▾ But it also has APIs for: ▾ Async ▾ SQLite ▾ Anko 0.9 introduced naming changes around the Async API ▾ Since Anko 0.10, Anko has support for coroutines LIBRARIES AND COROUTINES ON ANDROID
  • 41. #droidconVN LIBRARIES AND COROUTINES ON ANDROID COROUTINES IN ANKO ▾ Add anko-coroutines dependency ▾ Earlier versions of Anko already had support for async handling ▾ New: ▾ Coroutines in listeners ▾ bg() ▾ asReference() fun getData(): Data { ... } fun showData(data: Data) { ... } async(UI) { val data: Deferred<Data> = bg { // Runs on the background getData() } // This code is executed on the UI thread showData(data.await()) }
  • 42. #droidconVN LIBRARIES AND COROUTINES ON ANDROID COROUTINES WITH ASYNCAWAIT ▾ Async/await approach ▾ Very rich library on top of Kotlin’s coroutine core ▾ Plugins for RetroïŹt and rxJava async { val result = await { //Long running code } // Use result } async { val repos = await { github.getRepos() } showList(repos) repos.forEach { repo -> val stats = await { github.getStats (repo.name) } showStats(repo, stats) } }
  • 43. #droidconVN LIBRARIES AND COROUTINES ON ANDROID COROUTINES AND RXJAVA (I) ▾ There is an interop library for RX2 with coroutines: org.jetbrains.kotlinx:kotlinx- coroutines-rx2 ▾ rxJava -> coroutines: openSubscription(), awaitFirstOrDefault() ▾ coroutines -> rxJava: ▾ Job.asCompletable, Deferred.asSingle() ▾ Multiple coroutine builders: rxMaybe, rxCompletable etc.
  • 44. #droidconVN LIBRARIES AND COROUTINES ON ANDROID COROUTINES AND RXJAVA (II) ▾ Method count: ▾ Coroutines ~10-20% less than rxJava ▾ APK size: ▾ Similar, ~10-20% smaller than with rxJava ▾ Interop libraries add quite a lot to method count and APK size.
  • 45. OTHER THINGS AND FINAL THOUGHTS https://www.ïŹ‚ickr.com/photos/chrispiascik/4054331891
  • 46. #droidconVN OTHER THINGS & FINAL THOUGHTS UNIT TESTING SUSPENDING FUNCTIONS ▾ They need a coroutine to run, easiest way seems to be with runBlocking {
} import kotlinx.coroutines.experimental.runBlocking import org.testng.annotations.Test class MyTest { @Test fun testMySuspendingFunction() = runBlocking<Unit> { // your test code here } }
  • 47. #droidconVN OTHER THINGS & FINAL THOUGHTS EXPERIMENTAL? ▾ Coroutines are currently experimental in Kotlin 1.x, however: ▾ Very sound approach of dealing with concurrency ▾ Jetbrains guarantees backwards compatibility ▾ Potentially no forward compatibility ▾ Coroutines can and should be used in production ▾ Quite low learning curve compared to rxJava and other libraries
  • 48. #droidconVN OTHER THINGS RESOURCES ▾ Introduction to background processing in Android:‹ http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html ▾ Coroutines design document:‹ https://github.com/Kotlin/kotlin-coroutines ▾ Coroutines guide:‹ https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md ▾ Java Futures & Coroutines:‹ https://blog.frankel.ch/concurrency-java-futures-kotlin-coroutines/#gsc.tab=0 ▾ Anko: ‹ https://github.com/Kotlin/anko ▾ AsyncAwait:‹ https://github.com/metalabdesign/AsyncAwait ▾ Coroutines and reactive streams:‹ https://github.com/Kotlin/kotlinx.coroutines/blob/master/reactive/README.md
  • 49. #droidconVN OTHER THINGS GET IN TOUCH Kai Koenig Email: [email protected] Work: http://www.ventego-creative.co.nz Twitter: @AgentK Telegram: @kaikoenig Slides: http://www.slideshare.com/agentk