Reduce dependency
on Rx
with Kotlin
Coroutines
LINE Fukuoka
@umakoz
2019 1 23 LINE Developer Meetup #49 in KYOTO
About me
• LINE Fukuoka 3
•
• @umakoz
• LINE Creators Studio for Android
•
!
3°02'03"
LINE Creators Studio
• LINE
•
•
https://creator.line.me/ja/studio/
inside LINE Creators Studio
• Pure Kotlin without Library
• MVVM
• RxJava2, RxKotlin, RxLifecycle, Retrofit2, Realm...
Rx
ReactiveX
Reactive Extensions
An API for
asynchronous programming
with observable streams.
Rx
• Create
Easily create event streams or data streams.
• Combine
Compose and transform streams with query-like operators.
• Listen
Subscribe to any observable stream to perform side effects.
Rx
RxJava
A Java VM implementation of
Reactive Extensions
RxJava event/data stream
• Observable
0..N flows, no backpressure,
• Flowable
0..N flows, supporting Reactive-Streams and backpressure
RxJava event/data stream
• Single
a flow of exactly 1 item or an error,
• Completable
a flow without items but only a completion or error signal,
• Maybe
a flow with no items, exactly one item or an error.
async code using RxJava2
fun loadSticker(id: Int): Single<Sticker> = ...
loadSticker(id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ sticker -> show(sticker) },
{ error -> showError(error) }
)
difficulty of Rx
•
• Functional Programming
• Reactive Programming
• operator
http://reactivex.io/documentation/operators.html
• Hot / Cold
•
Kotlin 1.3 Released
Coroutines
Coroutines
: co-routine
co
https://ja.wikipedia.org/wiki/
async code using Coroutines
suspend fun loadSticker(id: Int): Sticker = ...
GlobalScope.launch(Dispatchers.Main) {
try {
val sticker = async(Dispatchers.IO) {
loadSticker(id)
}.await()
show(sticker)
} catch (error: Exception) {
showError(error)
}
}
Coroutine scope
A fundamental building block of coroutines.
• threading
• life-cycle
object GlobalScope : CoroutineScope
Coroutine builder
Starts coroutine from a regular non-suspending scope.
fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job
fun <T> CoroutineScope.async(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T>
Coroutine dispatcher
Ensures that the execution of a coroutine gets dispatched on
the right thread.
• Dispatchers.Main
• Dispatchers.Default
• Dispatchers.IO
• Dispatchers.Unconfined
suspend function
Suspends execution of the code without blocking the current
thread of execution.
suspend fun loadSticker(id: Int): Sticker = ...
async code using Coroutines
suspend fun loadSticker(id: Int): Sticker = ...
GlobalScope.launch(Dispatchers.Main) {
try {
val sticker = async(Dispatchers.IO) {
loadSticker(id)
}.await()
show(sticker)
} catch (error: Exception) {
showError(error)
}
}
Compare RxJava2 stream with
Coroutines
RxJava2 Coroutines
Observable ReceiveChannel (experimental)
Flowable ReceiveChannel (experimental)
Single Deferred
Completable Job
Maybe Deferred
kotlinx-coroutines-rx2
• Modules that provide builders and iteration support for
various reactive streams libraries:
• Reactive Streams, RxJava 2.x, and Project Reactor
https://github.com/Kotlin/kotlinx.coroutines/blob/master/
reactive/kotlinx-coroutines-rx2
RxJava2 to Coroutines
suspend fun <T> SingleSource<T>.await(): T
suspend fun CompletableSource.await(): Unit
suspend fun <T> MaybeSource<T>.await(): T?
Coroutines to RxJava2
fun CoroutineScope.rxSingle(...): Single
fun CoroutineScope.rxCompletable(...): Completable
fun CoroutineScope.rxMaybe(...): Maybe
How to use Coroutines on MVVM
retrofit2-kotlin-coroutines-adapter
A Retrofit 2 CallAdapter.Factory for RxJava2's Single.
interface MyService {
@GET("/sticker")
fun loadSticker(id: Int): Single<Sticker>
}
retrofit2-kotlin-coroutines-adapter
A Retrofit 2 CallAdapter.Factory for Kotlin coroutine's Deferred.
interface MyService {
@GET("/sticker")
fun loadSticker(id: Int): Deferred<Sticker>
}
https://github.com/JakeWharton/retrofit2-kotlin-coroutines-
adapter
Conclusion
• Coroutines
• RxJava2 Coroutines
• Coroutine Channel experimental
• API DB Coroutines
• View Rx Observable operator
Thank you

Reduce dependency on Rx with Kotlin Coroutines

  • 1.
    Reduce dependency on Rx withKotlin Coroutines LINE Fukuoka @umakoz 2019 1 23 LINE Developer Meetup #49 in KYOTO
  • 2.
    About me • LINEFukuoka 3 • • @umakoz • LINE Creators Studio for Android • ! 3°02'03"
  • 3.
    LINE Creators Studio •LINE • • https://creator.line.me/ja/studio/
  • 4.
    inside LINE CreatorsStudio • Pure Kotlin without Library • MVVM • RxJava2, RxKotlin, RxLifecycle, Retrofit2, Realm...
  • 5.
    Rx ReactiveX Reactive Extensions An APIfor asynchronous programming with observable streams.
  • 6.
    Rx • Create Easily createevent streams or data streams. • Combine Compose and transform streams with query-like operators. • Listen Subscribe to any observable stream to perform side effects.
  • 7.
  • 8.
    RxJava A Java VMimplementation of Reactive Extensions
  • 9.
    RxJava event/data stream •Observable 0..N flows, no backpressure, • Flowable 0..N flows, supporting Reactive-Streams and backpressure
  • 10.
    RxJava event/data stream •Single a flow of exactly 1 item or an error, • Completable a flow without items but only a completion or error signal, • Maybe a flow with no items, exactly one item or an error.
  • 11.
    async code usingRxJava2 fun loadSticker(id: Int): Single<Sticker> = ... loadSticker(id) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { sticker -> show(sticker) }, { error -> showError(error) } )
  • 12.
    difficulty of Rx • •Functional Programming • Reactive Programming • operator http://reactivex.io/documentation/operators.html • Hot / Cold •
  • 13.
  • 14.
  • 15.
    async code usingCoroutines suspend fun loadSticker(id: Int): Sticker = ... GlobalScope.launch(Dispatchers.Main) { try { val sticker = async(Dispatchers.IO) { loadSticker(id) }.await() show(sticker) } catch (error: Exception) { showError(error) } }
  • 16.
    Coroutine scope A fundamentalbuilding block of coroutines. • threading • life-cycle object GlobalScope : CoroutineScope
  • 17.
    Coroutine builder Starts coroutinefrom a regular non-suspending scope. fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job fun <T> CoroutineScope.async( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> T ): Deferred<T>
  • 18.
    Coroutine dispatcher Ensures thatthe execution of a coroutine gets dispatched on the right thread. • Dispatchers.Main • Dispatchers.Default • Dispatchers.IO • Dispatchers.Unconfined
  • 19.
    suspend function Suspends executionof the code without blocking the current thread of execution. suspend fun loadSticker(id: Int): Sticker = ...
  • 20.
    async code usingCoroutines suspend fun loadSticker(id: Int): Sticker = ... GlobalScope.launch(Dispatchers.Main) { try { val sticker = async(Dispatchers.IO) { loadSticker(id) }.await() show(sticker) } catch (error: Exception) { showError(error) } }
  • 21.
    Compare RxJava2 streamwith Coroutines RxJava2 Coroutines Observable ReceiveChannel (experimental) Flowable ReceiveChannel (experimental) Single Deferred Completable Job Maybe Deferred
  • 22.
    kotlinx-coroutines-rx2 • Modules thatprovide builders and iteration support for various reactive streams libraries: • Reactive Streams, RxJava 2.x, and Project Reactor https://github.com/Kotlin/kotlinx.coroutines/blob/master/ reactive/kotlinx-coroutines-rx2
  • 23.
    RxJava2 to Coroutines suspendfun <T> SingleSource<T>.await(): T suspend fun CompletableSource.await(): Unit suspend fun <T> MaybeSource<T>.await(): T?
  • 24.
    Coroutines to RxJava2 funCoroutineScope.rxSingle(...): Single fun CoroutineScope.rxCompletable(...): Completable fun CoroutineScope.rxMaybe(...): Maybe
  • 25.
    How to useCoroutines on MVVM
  • 26.
    retrofit2-kotlin-coroutines-adapter A Retrofit 2CallAdapter.Factory for RxJava2's Single. interface MyService { @GET("/sticker") fun loadSticker(id: Int): Single<Sticker> }
  • 27.
    retrofit2-kotlin-coroutines-adapter A Retrofit 2CallAdapter.Factory for Kotlin coroutine's Deferred. interface MyService { @GET("/sticker") fun loadSticker(id: Int): Deferred<Sticker> } https://github.com/JakeWharton/retrofit2-kotlin-coroutines- adapter
  • 28.
    Conclusion • Coroutines • RxJava2Coroutines • Coroutine Channel experimental • API DB Coroutines • View Rx Observable operator
  • 29.