SlideShare a Scribd company logo
Kotlin Coroutine - the next step
for RxJava developer?
Artur Latoszewski
Agenda:
1. Pre-Kotlin world
2. What are coroutines and why we need it
3. Theoretical knowledge
4. Basic tutorial (some code)
5. Extra examples (more code)
6. Answer for the title question
7. Where to find more information
What have we had in pre-Kotlin world?
● AsyncTasks
● Threads
Painful points:
● Android Lifecycle
● Awful API
● Callbacks
● Easy to make a bug
● Hard to debug
● Concurrency is hard
What have we had in pre-Kotlin world? - RxJava!
http://reactivex.io/
We are Kotliners!
What are Coroutines for a developer?
Coroutines allows us to write asynchronous code in
sequential way.
fun loadData() {
var data = api.getData()
showData(data)
}
sequential code
(not coroutine)
What problem does it solve?
What problem does it solve? Callbacks!
https://www.twilio.com/blog/2017/03/promises-in-swift-writing-cleaner-asynchronous-code-using-promisekit.html
RxJava problems?
Observable.just(1,2,3,4)
.map { /*someMapping*/ }
.filter { /*someFilter*/ }
.subscribe(
{ /*onNext*/ },
{ /*onError*/ }
)
RxJava problems?
Observable.just(1,2,3,4)
.map { /*someMapping*/ }
.filter { /*someFilter*/ }
.subscribe(
{ /*onNext*/ },
{ /*onError*/ }
)
Callbacks
RxJava problems?
Observable.just(1,2,3,4)
.map { /*someMapping*/ }
.filter { /*someFilter*/ }
.subscribe(
{ /*onNext*/ },
{ /*onError*/ }
)
Callbacks
Stream style
Theoretical knowledge
Coroutines - deep dive
● conceptually very light-weight threads
● one thread = ∞ coroutines
● compiled to state machine with shared state (and callbacks)
● 100K Threads = 💔, 100K Coroutines = 💚
● less context switch overhead
● less memory overhead
● works everywhere where Kotlin works
● stable since Kotlin 1.3
Suspend function
● suspend and executed later
● without blocking thread
● without changing context
● almost free
suspend fun doWorld() {
println("World!")
}
Coroutine context = Job + Dispatcher
Job (Rx ~ CompositeDisposable)
● a cancellable thing
● can’t be reused after cancel
● parent-child hierarchies
● SupervisorJob - child don’t cancel parent
Dispatchers (Rx ~ Schedulers)
● Default - thread pool = CPU cores
● Main - run on main thread (main UI thread on Android)
● IO - designed for IO tasks, share with Default
● launch() - fire and forget
○ return Job object - allows to cancel coroutine
○ uncaught exceptions = crash
● async() - promise that it will return object
○ return Deferred<out T> : Job on which we call await() to wait for result
○ without await() call it will “swallow” exception
● runBlocking() - locks current thread until end of execution
● withContext() - run internal block on specified context
Coroutine builder
Kotlin coroutine - the next step for RxJava developer?
Coroutines - first
launch{
println("We are in coroutine")
}
Coroutines - first
val job = GlobalScope.launch(Dispatchers.Main){
println("We are in coroutine")
}
Coroutines - cancel
val job = GlobalScope.launch(Dispatchers.Main){
println("We are in coroutine")
}
job.cancel()
------------------------------------------------------------------
RxJava disposable.dispose()
Coroutines - cancel
val job = launch (Dispatchers.Main){
while (true){
println("We are in coroutine")
}
}
job.cancel()
Coroutines - cancel
val job = launch (Dispatchers.Main){
while (isActive){
println("We are in coroutine")
}
}
job.cancel()
------------------------------------------------------------------
RxJava isDisposed()
CoroutineScope
public interface CoroutineScope {
public val coroutineContext: CoroutineContext
}
● every coroutine needs a scope (coroutine is extension method)
● scope is a lifecycle for a coroutine
● scopes creates “scope tree”
● you don’t want to use GlobalScope
CoroutineScope - Activty
class MyActivity : AppCompatActivity(), CoroutineScope {
lateinit var parentJob: SupervisorJob
override val coroutineContext: CoroutineContext = Dispatchers.Main + parentJob
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
parentJob = SupervisorJob()
}
override fun onDestroy() {
super.onDestroy()
parentJob.cancel()
}
}
CoroutineScope - Activty
class MyActivity : AppCompatActivity(), CoroutineScope {
override val coroutineContext: CoroutineContext = Dispatchers.Main + parentJob
fun buildCoroutineTree(){
launch { // MyActivity scope
async { // launch scope }
}
launch { // MyActivity scope }
}
override fun onDestroy() {
parentJob.cancel() // Cancel all coroutines in scope
}
}
CoroutineScope - ViewModel
class MyActivity : ViewModel(), CoroutineScope {
val parentJob = SupervisorJob()
override val coroutineContext: CoroutineContext = Dispatchers.Main + parentJob
override fun onCleared() {
super.onCleared()
parentJob.cancel()
}
fun doSomeStuff() {
launch{ // launch scope }
}
}
CoroutineScope - ViewModel
class MyActivity : ViewModel(), CoroutineScope {
fun doSomeStuff() {
viewModelScope.launch{ // launch scope }
}
}
● AndroidX Lifecycle v2.1.0 (alpha)
Coroutines - change context (thread)
launch (Dispatchers.Main){
println("Coroutine in main thread")
withContext(Dispatchers.IO){
println("Coroutine in background thread")
}
println("Coroutine in main thread")
}
------------------------------------------------------------------
RxJava
.observeOn()
.subscribeOn()
.unsubscribeOn()
Coroutines - sequentially
fun loadDataSequentially() {
launch(Dispatchers.Main) {
val response1 = withContext(Dispatchers.IO) { loadData1() } // 1
val response2 = withContext(Dispatchers.IO) { loadData2() } // 2
val result = response1 + response2 // 3
}
}
Coroutines - sequentially
fun loadDataSequentially() {
launch(Dispatchers.Main) {
val response1 = withContext(Dispatchers.IO) { loadData1() } // 1
val response2 = withContext(Dispatchers.IO) { loadData2() } // 2
val result = response1 + response2 // 3
}
}
Coroutines - asynchronous
launch(Dispatchers.Main) {
val response = async(Dispatchers.IO) { // Deferred<Response>
println("We are in async coroutine")
// doing stuff in background thread
loadData()
}
// doing stuff main thread
val value = response.await() // await for response
}
Coroutines - parallel
fun loadDataParallel() {
launch(Dispatchers.Main) {
val response1 = async(Dispatchers.IO) { loadData1() }
val response2 = async(Dispatchers.IO) { loadData2() }
// doing stuff main thread
val result = response1.await() + response1.await() //await for response
}
}
Coroutines - parallel
fun loadDataParallel() {
launch(Dispatchers.Main) {
val response1 = async(Dispatchers.IO) { loadData1() }
val response2 = async(Dispatchers.IO) { loadData2() }
// doing stuff main thread
val result = response1.await() + response1.await() //await for response
}
}
More complex examples
RxJava
vs
Coroutine
Dmytro Danylyk
@dmytrodanylyk
Android/Kotlin Google
Developer Expert
Operators?
Everything from Kotlin Collections (map, filter, etc.) and more:
fun loadDataWithTimeout() {
launch(Dispatchers.Main) {
val response = async(Dispatchers.IO) { loadData() }
val result = withTimeoutOrNull(2, TimeUnit.SECONDS) { response.await() }
}
Retry
suspend fun <T> retry(block: suspend (Int) -> T): T {
for (i in 1..5) { // try 5 times
try {
return withTimeout(500) { // with timeout
block(i)
}
} catch (e: TimeoutCancellationException) { /* retry */ }
}
return block(0) // last time just invoke without timeout
}
Retry
suspend fun <T> retry(block: suspend (Int) -> T): T {
for (i in 1..5) { // try 5 times
try {
return withTimeout(500) { // with timeout
block(i)
}
} catch (e: TimeoutCancellationException) { /* retry */ }
}
return block(0) // last time just invoke without timeout
}
Retry
suspend fun <T> retry(block: suspend (Int) -> T): T {
for (i in 1..5) { // try 5 times
try {
return withTimeout(500) { // with timeout
block(i)
}
} catch (e: TimeoutCancellationException) { /* retry */ }
}
return block(0) // last time just invoke without timeout
}
Retry
suspend fun <T> retry(block: suspend (Int) -> T): T {
for (i in 1..5) { // try 5 times
try {
return withTimeout(500) { // with timeout
block(i)
}
} catch (e: TimeoutCancellationException) { /* retry */ }
}
return block(0) // last time just invoke without timeout
}
Retry
suspend fun <T> retry(block: suspend (Int) -> T): T {
for (i in 1..5) { // try 5 times
try {
return withTimeout(500) { // with timeout
block(i)
}
} catch (e: TimeoutCancellationException) { /* retry */ }
}
return block(0) // last time just invoke without timeout
}
Retry
suspend fun <T> retry(block: suspend (Int) -> T): T {
for (i in 1..5) { // try 5 times
try {
return withTimeout(500) { // with timeout
block(i)
}
} catch (e: TimeoutCancellationException) { /* retry */ }
}
return block(0) // last time just invoke without timeout
}
Retrofit
interface RemoteDataSource{
@GET("api/news")
fun getNews() : Single<NewsResponse>
}
------------------------------------------------------------------
interface RemoteDataSource {
@GET("api/news")
fun getNews(): Deferred<NewsResponse>
}
------------------------------------------------------------------
interface RemoteDataSource {
@GET("api/news")
suspend fun getNews(): NewsResponse
}
RxJava
Adapter by
JakeWharton
Retrofit 2.5.1
Channels
● experimental
● hot observables in Rx world
● have buffer (default is 1)
● cold observables -
top issue
● cold observables ~
Sequences
val channel = Channel<Int>(1) // capacity 1
//Execution order
fun channelSend() = launch {
channel.send(1) //1
channel.send(1) //3
}
fun channelReceive() = launch {
val value1 = channel.receive() //2
val value2 = channel.receive() //4
}
Channels
● experimental
● hot observables in Rx world
● have buffer (default is 1)
● cold observables -
top issue
● cold observables ~
Sequences
val channel = Channel<Int>(1) // capacity 1
//Execution order
fun channelSend() = launch {
channel.send(1) //1
channel.send(1) //3
}
fun channelReceive() = launch {
val value1 = channel.receive() //2
val value2 = channel.receive() //4
}
Channels
● experimental
● hot observables in Rx world
● have buffer (default is 1)
● cold observables -
top issue
● cold observables ~
Sequences
val channel = Channel<Int>(1) // capacity 1
//Execution order
fun channelSend() = launch {
channel.send(1) //1
channel.send(1) //3
}
fun channelReceive() = launch {
val value1 = channel.receive() //2
val value2 = channel.receive() //4
}
Channels
● experimental
● hot observables in Rx world
● have buffer (default is 1)
● cold observables -
top issue
● cold observables ~
Sequences
val channel = Channel<Int>(1) // capacity 1
//Execution order
fun channelSend() = launch {
channel.send(1) //1
channel.send(1) //3
}
fun channelReceive() = launch {
val value1 = channel.receive() //2
val value2 = channel.receive() //4
}
Channels
● experimental
● hot observables in Rx world
● have buffer (default is 1)
● cold observables -
top issue
● cold observables ~
Sequences
val channel = Channel<Int>(1) // capacity 1
//Execution order
fun channelSend() = launch {
channel.send(1) //1
channel.send(1) //3
}
fun channelReceive() = launch {
val value1 = channel.receive() //2
val value2 = channel.receive() //4
}
Channels
● experimental
● hot observables in Rx world
● have buffer (default is 1)
● cold observables -
top issue
● cold observables ~
Sequences
val channel = Channel<Int>(1) // capacity 1
//Execution order
fun channelSend() = launch {
channel.send(1) //1
channel.send(1) //3
}
fun channelReceive() = launch {
val value1 = channel.receive() //2
val value2 = channel.receive() //4
}
Produce
val producer = produce{
send(1) //1
send(1) //3
}
fun receive() {
launch {
val value1 = producer.receive() //2
val value2 = producer.receive() //4
}
}
Actor
val subscriber = actor<Int> {
for(i in channel) {
//wait for elements in channel
}
}
fun send() {
launch {
subscriber.send(1)
subscriber.send(2)
}
}
Will it be the next step for RxJava
developer?
The next step for RxJava developer?
● Coroutines = low-level API for asynchronous calls
● Rx = observable pattern, "functional reactive programming"
● sequential vs streams, next tool in toolset
● Coroutines are faster and more memory efficient
● Perfectly replacement for Single, Completable, Maybe
● Easier to learn, lower entry threshold
● Can pass null values
● Channels can’t replace Observables
● Rx wins when dealing with real streams
● Coroutine wins with Kotlin/Native
● Rx API with Coroutines?
Should we switch to coroutines? IMHO
● You already have RxJava - stay with RxJava
● You are in love with RxJava - good
● You work with streams - only Rx
● You work with Java - Rx
● CRUD - Coroutines
● Simple app - Coroutines
● Don’t want Rx - only Coroutines
Where/What to learn more?
● https://github.com/Kotlin/kotlin-coroutines/ - core coroutine in language
● https://github.com/Kotlin/kotlinx.coroutines - base support library and other:
○ Dispatchers(“threads”) for Dispatchers.Main - Android, Spring, JavaFX
○ support for Reactive libraries - RxJava1, RxJava2, etc…
○ support for future-based libraries - JDK8, Guava, etc…
○ Kotlin/JS
○ Kotlin/Native
● KotlinConf talks about Coroutines by Roman Elizarov (2017, 2018)
Questions?
Coroutines, Kotlin, Ultimate Question of Life, the Universe,
and Everything?
@iiarchi
thecodeside.com

More Related Content

PDF
droidcon Transylvania - Kotlin Coroutines
PDF
Current State of Coroutines
PDF
Silicon Valley JUG: JVM Mechanics
PDF
Metaprogramming and Reflection in Common Lisp
PDF
Something about Golang
PDF
#JavaFX.forReal() - ElsassJUG
PDF
sizeof(Object): how much memory objects take on JVMs and when this may matter
PDF
Java Concurrency Idioms
droidcon Transylvania - Kotlin Coroutines
Current State of Coroutines
Silicon Valley JUG: JVM Mechanics
Metaprogramming and Reflection in Common Lisp
Something about Golang
#JavaFX.forReal() - ElsassJUG
sizeof(Object): how much memory objects take on JVMs and when this may matter
Java Concurrency Idioms

What's hot (20)

PDF
.NET Multithreading and File I/O
PDF
Python Async IO Horizon
PDF
Actor Concurrency
PPTX
Making Java more dynamic: runtime code generation for the JVM
KEY
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
PDF
Kotlin from-scratch 3 - coroutines
PDF
Non stop random2b
PPT
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
PDF
Concurrency Concepts in Java
ODP
Java Concurrency
PDF
C++ game development with oxygine
TXT
Play image
PDF
Oxygine 2 d objects,events,debug and resources
PDF
Java 7 LavaJUG
PDF
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
PDF
Java Concurrency Gotchas
PDF
soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin
PPTX
Effective java - concurrency
PDF
Java Concurrency Gotchas
PDF
asyncio internals
.NET Multithreading and File I/O
Python Async IO Horizon
Actor Concurrency
Making Java more dynamic: runtime code generation for the JVM
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Kotlin from-scratch 3 - coroutines
Non stop random2b
About Those Python Async Concurrent Frameworks - Fantix @ OSTC 2014
Concurrency Concepts in Java
Java Concurrency
C++ game development with oxygine
Play image
Oxygine 2 d objects,events,debug and resources
Java 7 LavaJUG
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java Concurrency Gotchas
soft-shake.ch - Java SE 7: The Fork/Join Framework and Project Coin
Effective java - concurrency
Java Concurrency Gotchas
asyncio internals
Ad

Similar to Kotlin coroutine - the next step for RxJava developer? (20)

PPTX
Coroutines talk ppt
PDF
Improving app performance with Kotlin Coroutines
PDF
Quick Introduction to Kotlin Coroutine for Android Dev
PDF
Should it be routine to use coroutines?
PDF
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
PDF
Kotlin - Coroutine
PDF
Structured concurrency with Kotlin Coroutines
PPTX
Kotlin Coroutines and Rx
PDF
Coroutines in Kotlin. In-depth review
PDF
Coroutines in Kotlin. UA Mobile 2017.
PDF
Coroutines and RxJava - An Asynchronicity Comparison
PDF
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
PDF
Asynchronous Programming in Kotlin with Coroutines
PPTX
Coroutines in Kotlin
PDF
Programação assíncrona utilizando Coroutines
PDF
Introduction to kotlin coroutines
PDF
KOTLIN COROUTINES - PART 1
PDF
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
PPTX
Kotlin coroutines and spring framework
PDF
Coroutines for Kotlin Multiplatform in Practise
Coroutines talk ppt
Improving app performance with Kotlin Coroutines
Quick Introduction to Kotlin Coroutine for Android Dev
Should it be routine to use coroutines?
Fabio Collini - Async code on Kotlin: RxJava or/and coroutines - Codemotion M...
Kotlin - Coroutine
Structured concurrency with Kotlin Coroutines
Kotlin Coroutines and Rx
Coroutines in Kotlin. In-depth review
Coroutines in Kotlin. UA Mobile 2017.
Coroutines and RxJava - An Asynchronicity Comparison
Threading Made Easy! A Busy Developer’s Guide to Kotlin Coroutines
Asynchronous Programming in Kotlin with Coroutines
Coroutines in Kotlin
Programação assíncrona utilizando Coroutines
Introduction to kotlin coroutines
KOTLIN COROUTINES - PART 1
Async code on kotlin: rx java or/and coroutines - Kotlin Night Turin
Kotlin coroutines and spring framework
Coroutines for Kotlin Multiplatform in Practise
Ad

Recently uploaded (20)

PDF
System and Network Administration Chapter 2
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Nekopoi APK 2025 free lastest update
PPTX
ai tools demonstartion for schools and inter college
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
Odoo POS Development Services by CandidRoot Solutions
PDF
AI in Product Development-omnex systems
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
PTS Company Brochure 2025 (1).pdf.......
PPTX
Essential Infomation Tech presentation.pptx
System and Network Administration Chapter 2
How to Migrate SBCGlobal Email to Yahoo Easily
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Odoo Companies in India – Driving Business Transformation.pdf
Nekopoi APK 2025 free lastest update
ai tools demonstartion for schools and inter college
Upgrade and Innovation Strategies for SAP ERP Customers
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Softaken Excel to vCard Converter Software.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
Odoo POS Development Services by CandidRoot Solutions
AI in Product Development-omnex systems
Design an Analysis of Algorithms I-SECS-1021-03
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Which alternative to Crystal Reports is best for small or large businesses.pdf
PTS Company Brochure 2025 (1).pdf.......
Essential Infomation Tech presentation.pptx

Kotlin coroutine - the next step for RxJava developer?

  • 1. Kotlin Coroutine - the next step for RxJava developer? Artur Latoszewski
  • 2. Agenda: 1. Pre-Kotlin world 2. What are coroutines and why we need it 3. Theoretical knowledge 4. Basic tutorial (some code) 5. Extra examples (more code) 6. Answer for the title question 7. Where to find more information
  • 3. What have we had in pre-Kotlin world? ● AsyncTasks ● Threads Painful points: ● Android Lifecycle ● Awful API ● Callbacks ● Easy to make a bug ● Hard to debug ● Concurrency is hard
  • 4. What have we had in pre-Kotlin world? - RxJava! http://reactivex.io/
  • 6. What are Coroutines for a developer? Coroutines allows us to write asynchronous code in sequential way. fun loadData() { var data = api.getData() showData(data) } sequential code (not coroutine)
  • 7. What problem does it solve?
  • 8. What problem does it solve? Callbacks! https://www.twilio.com/blog/2017/03/promises-in-swift-writing-cleaner-asynchronous-code-using-promisekit.html
  • 9. RxJava problems? Observable.just(1,2,3,4) .map { /*someMapping*/ } .filter { /*someFilter*/ } .subscribe( { /*onNext*/ }, { /*onError*/ } )
  • 10. RxJava problems? Observable.just(1,2,3,4) .map { /*someMapping*/ } .filter { /*someFilter*/ } .subscribe( { /*onNext*/ }, { /*onError*/ } ) Callbacks
  • 11. RxJava problems? Observable.just(1,2,3,4) .map { /*someMapping*/ } .filter { /*someFilter*/ } .subscribe( { /*onNext*/ }, { /*onError*/ } ) Callbacks Stream style
  • 13. Coroutines - deep dive ● conceptually very light-weight threads ● one thread = ∞ coroutines ● compiled to state machine with shared state (and callbacks) ● 100K Threads = 💔, 100K Coroutines = 💚 ● less context switch overhead ● less memory overhead ● works everywhere where Kotlin works ● stable since Kotlin 1.3
  • 14. Suspend function ● suspend and executed later ● without blocking thread ● without changing context ● almost free suspend fun doWorld() { println("World!") }
  • 15. Coroutine context = Job + Dispatcher Job (Rx ~ CompositeDisposable) ● a cancellable thing ● can’t be reused after cancel ● parent-child hierarchies ● SupervisorJob - child don’t cancel parent Dispatchers (Rx ~ Schedulers) ● Default - thread pool = CPU cores ● Main - run on main thread (main UI thread on Android) ● IO - designed for IO tasks, share with Default
  • 16. ● launch() - fire and forget ○ return Job object - allows to cancel coroutine ○ uncaught exceptions = crash ● async() - promise that it will return object ○ return Deferred<out T> : Job on which we call await() to wait for result ○ without await() call it will “swallow” exception ● runBlocking() - locks current thread until end of execution ● withContext() - run internal block on specified context Coroutine builder
  • 19. Coroutines - first val job = GlobalScope.launch(Dispatchers.Main){ println("We are in coroutine") }
  • 20. Coroutines - cancel val job = GlobalScope.launch(Dispatchers.Main){ println("We are in coroutine") } job.cancel() ------------------------------------------------------------------ RxJava disposable.dispose()
  • 21. Coroutines - cancel val job = launch (Dispatchers.Main){ while (true){ println("We are in coroutine") } } job.cancel()
  • 22. Coroutines - cancel val job = launch (Dispatchers.Main){ while (isActive){ println("We are in coroutine") } } job.cancel() ------------------------------------------------------------------ RxJava isDisposed()
  • 23. CoroutineScope public interface CoroutineScope { public val coroutineContext: CoroutineContext } ● every coroutine needs a scope (coroutine is extension method) ● scope is a lifecycle for a coroutine ● scopes creates “scope tree” ● you don’t want to use GlobalScope
  • 24. CoroutineScope - Activty class MyActivity : AppCompatActivity(), CoroutineScope { lateinit var parentJob: SupervisorJob override val coroutineContext: CoroutineContext = Dispatchers.Main + parentJob override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) parentJob = SupervisorJob() } override fun onDestroy() { super.onDestroy() parentJob.cancel() } }
  • 25. CoroutineScope - Activty class MyActivity : AppCompatActivity(), CoroutineScope { override val coroutineContext: CoroutineContext = Dispatchers.Main + parentJob fun buildCoroutineTree(){ launch { // MyActivity scope async { // launch scope } } launch { // MyActivity scope } } override fun onDestroy() { parentJob.cancel() // Cancel all coroutines in scope } }
  • 26. CoroutineScope - ViewModel class MyActivity : ViewModel(), CoroutineScope { val parentJob = SupervisorJob() override val coroutineContext: CoroutineContext = Dispatchers.Main + parentJob override fun onCleared() { super.onCleared() parentJob.cancel() } fun doSomeStuff() { launch{ // launch scope } } }
  • 27. CoroutineScope - ViewModel class MyActivity : ViewModel(), CoroutineScope { fun doSomeStuff() { viewModelScope.launch{ // launch scope } } } ● AndroidX Lifecycle v2.1.0 (alpha)
  • 28. Coroutines - change context (thread) launch (Dispatchers.Main){ println("Coroutine in main thread") withContext(Dispatchers.IO){ println("Coroutine in background thread") } println("Coroutine in main thread") } ------------------------------------------------------------------ RxJava .observeOn() .subscribeOn() .unsubscribeOn()
  • 29. Coroutines - sequentially fun loadDataSequentially() { launch(Dispatchers.Main) { val response1 = withContext(Dispatchers.IO) { loadData1() } // 1 val response2 = withContext(Dispatchers.IO) { loadData2() } // 2 val result = response1 + response2 // 3 } }
  • 30. Coroutines - sequentially fun loadDataSequentially() { launch(Dispatchers.Main) { val response1 = withContext(Dispatchers.IO) { loadData1() } // 1 val response2 = withContext(Dispatchers.IO) { loadData2() } // 2 val result = response1 + response2 // 3 } }
  • 31. Coroutines - asynchronous launch(Dispatchers.Main) { val response = async(Dispatchers.IO) { // Deferred<Response> println("We are in async coroutine") // doing stuff in background thread loadData() } // doing stuff main thread val value = response.await() // await for response }
  • 32. Coroutines - parallel fun loadDataParallel() { launch(Dispatchers.Main) { val response1 = async(Dispatchers.IO) { loadData1() } val response2 = async(Dispatchers.IO) { loadData2() } // doing stuff main thread val result = response1.await() + response1.await() //await for response } }
  • 33. Coroutines - parallel fun loadDataParallel() { launch(Dispatchers.Main) { val response1 = async(Dispatchers.IO) { loadData1() } val response2 = async(Dispatchers.IO) { loadData2() } // doing stuff main thread val result = response1.await() + response1.await() //await for response } }
  • 36. Operators? Everything from Kotlin Collections (map, filter, etc.) and more: fun loadDataWithTimeout() { launch(Dispatchers.Main) { val response = async(Dispatchers.IO) { loadData() } val result = withTimeoutOrNull(2, TimeUnit.SECONDS) { response.await() } }
  • 37. Retry suspend fun <T> retry(block: suspend (Int) -> T): T { for (i in 1..5) { // try 5 times try { return withTimeout(500) { // with timeout block(i) } } catch (e: TimeoutCancellationException) { /* retry */ } } return block(0) // last time just invoke without timeout }
  • 38. Retry suspend fun <T> retry(block: suspend (Int) -> T): T { for (i in 1..5) { // try 5 times try { return withTimeout(500) { // with timeout block(i) } } catch (e: TimeoutCancellationException) { /* retry */ } } return block(0) // last time just invoke without timeout }
  • 39. Retry suspend fun <T> retry(block: suspend (Int) -> T): T { for (i in 1..5) { // try 5 times try { return withTimeout(500) { // with timeout block(i) } } catch (e: TimeoutCancellationException) { /* retry */ } } return block(0) // last time just invoke without timeout }
  • 40. Retry suspend fun <T> retry(block: suspend (Int) -> T): T { for (i in 1..5) { // try 5 times try { return withTimeout(500) { // with timeout block(i) } } catch (e: TimeoutCancellationException) { /* retry */ } } return block(0) // last time just invoke without timeout }
  • 41. Retry suspend fun <T> retry(block: suspend (Int) -> T): T { for (i in 1..5) { // try 5 times try { return withTimeout(500) { // with timeout block(i) } } catch (e: TimeoutCancellationException) { /* retry */ } } return block(0) // last time just invoke without timeout }
  • 42. Retry suspend fun <T> retry(block: suspend (Int) -> T): T { for (i in 1..5) { // try 5 times try { return withTimeout(500) { // with timeout block(i) } } catch (e: TimeoutCancellationException) { /* retry */ } } return block(0) // last time just invoke without timeout }
  • 43. Retrofit interface RemoteDataSource{ @GET("api/news") fun getNews() : Single<NewsResponse> } ------------------------------------------------------------------ interface RemoteDataSource { @GET("api/news") fun getNews(): Deferred<NewsResponse> } ------------------------------------------------------------------ interface RemoteDataSource { @GET("api/news") suspend fun getNews(): NewsResponse } RxJava Adapter by JakeWharton Retrofit 2.5.1
  • 44. Channels ● experimental ● hot observables in Rx world ● have buffer (default is 1) ● cold observables - top issue ● cold observables ~ Sequences val channel = Channel<Int>(1) // capacity 1 //Execution order fun channelSend() = launch { channel.send(1) //1 channel.send(1) //3 } fun channelReceive() = launch { val value1 = channel.receive() //2 val value2 = channel.receive() //4 }
  • 45. Channels ● experimental ● hot observables in Rx world ● have buffer (default is 1) ● cold observables - top issue ● cold observables ~ Sequences val channel = Channel<Int>(1) // capacity 1 //Execution order fun channelSend() = launch { channel.send(1) //1 channel.send(1) //3 } fun channelReceive() = launch { val value1 = channel.receive() //2 val value2 = channel.receive() //4 }
  • 46. Channels ● experimental ● hot observables in Rx world ● have buffer (default is 1) ● cold observables - top issue ● cold observables ~ Sequences val channel = Channel<Int>(1) // capacity 1 //Execution order fun channelSend() = launch { channel.send(1) //1 channel.send(1) //3 } fun channelReceive() = launch { val value1 = channel.receive() //2 val value2 = channel.receive() //4 }
  • 47. Channels ● experimental ● hot observables in Rx world ● have buffer (default is 1) ● cold observables - top issue ● cold observables ~ Sequences val channel = Channel<Int>(1) // capacity 1 //Execution order fun channelSend() = launch { channel.send(1) //1 channel.send(1) //3 } fun channelReceive() = launch { val value1 = channel.receive() //2 val value2 = channel.receive() //4 }
  • 48. Channels ● experimental ● hot observables in Rx world ● have buffer (default is 1) ● cold observables - top issue ● cold observables ~ Sequences val channel = Channel<Int>(1) // capacity 1 //Execution order fun channelSend() = launch { channel.send(1) //1 channel.send(1) //3 } fun channelReceive() = launch { val value1 = channel.receive() //2 val value2 = channel.receive() //4 }
  • 49. Channels ● experimental ● hot observables in Rx world ● have buffer (default is 1) ● cold observables - top issue ● cold observables ~ Sequences val channel = Channel<Int>(1) // capacity 1 //Execution order fun channelSend() = launch { channel.send(1) //1 channel.send(1) //3 } fun channelReceive() = launch { val value1 = channel.receive() //2 val value2 = channel.receive() //4 }
  • 50. Produce val producer = produce{ send(1) //1 send(1) //3 } fun receive() { launch { val value1 = producer.receive() //2 val value2 = producer.receive() //4 } }
  • 51. Actor val subscriber = actor<Int> { for(i in channel) { //wait for elements in channel } } fun send() { launch { subscriber.send(1) subscriber.send(2) } }
  • 52. Will it be the next step for RxJava developer?
  • 53. The next step for RxJava developer? ● Coroutines = low-level API for asynchronous calls ● Rx = observable pattern, "functional reactive programming" ● sequential vs streams, next tool in toolset ● Coroutines are faster and more memory efficient ● Perfectly replacement for Single, Completable, Maybe ● Easier to learn, lower entry threshold ● Can pass null values ● Channels can’t replace Observables ● Rx wins when dealing with real streams ● Coroutine wins with Kotlin/Native ● Rx API with Coroutines?
  • 54. Should we switch to coroutines? IMHO ● You already have RxJava - stay with RxJava ● You are in love with RxJava - good ● You work with streams - only Rx ● You work with Java - Rx ● CRUD - Coroutines ● Simple app - Coroutines ● Don’t want Rx - only Coroutines
  • 55. Where/What to learn more? ● https://github.com/Kotlin/kotlin-coroutines/ - core coroutine in language ● https://github.com/Kotlin/kotlinx.coroutines - base support library and other: ○ Dispatchers(“threads”) for Dispatchers.Main - Android, Spring, JavaFX ○ support for Reactive libraries - RxJava1, RxJava2, etc… ○ support for future-based libraries - JDK8, Guava, etc… ○ Kotlin/JS ○ Kotlin/Native ● KotlinConf talks about Coroutines by Roman Elizarov (2017, 2018)
  • 56. Questions? Coroutines, Kotlin, Ultimate Question of Life, the Universe, and Everything? @iiarchi thecodeside.com