Slide 1

Slide 1 text

RxJavaを使っている 既存アプリに Kotlin Coroutinesを導⼊しよう takahirom CyberAgent, Inc.

Slide 2

Slide 2 text

みなさんのアプリは
 だいたいRxJava 使ってますよね?

Slide 3

Slide 3 text

実際のアプリでは
 Observableより Single, Completable, Maybeが
 多いのでは?

Slide 4

Slide 4 text

SingleなどよりKotlin Coroutinesの suspend functionのほうが優れている

Slide 5

Slide 5 text

SingleなどはCoroutineに 置き換えたい!

Slide 6

Slide 6 text

置き換えるサンプルを
 ⽤意してみました。

Slide 7

Slide 7 text

こんな感じのサンプル 7JFX 7JFX.PEFM Method call "QJ Single> LiveData>

Slide 8

Slide 8 text

Singleをsuspend functionに 7JFX 7JFX.PEFM "QJ Single> LiveData> 7JFX 7JFX.PEFM "QJ suspend List LiveData>

Slide 9

Slide 9 text

前提の説明: RxJavaの例 class ViewModel( private val api: Api = Api(), private val scheduler: Scheduler = Schedulers.io() ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { api.fetchPersons() .subscribeOn(scheduler) .subscribe(mutablePersons::postValue) }} }}

Slide 10

Slide 10 text

前提の説明: RxJavaの例 class ViewModel( private val api: Api = Api(), private val scheduler: Scheduler = Schedulers.io() ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { api.fetchPersons() .subscribeOn(scheduler) .subscribe(mutablePersons::postValue) }} }} Activityから呼び出す

Slide 11

Slide 11 text

前提の説明: RxJavaの例 class ViewModel( private val api: Api = Api(), private val scheduler: Scheduler = Schedulers.io() ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { api.fetchPersons() .subscribeOn(scheduler) .subscribe(mutablePersons::postValue) }} }} Api#fetchPersonsがSingleを返してくる

Slide 12

Slide 12 text

前提の説明: RxJavaの例 class ViewModel( private val api: Api = Api(), private val scheduler: Scheduler = Schedulers.io() ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { api.fetchPersons() .subscribeOn(scheduler) .subscribe(mutablePersons::postValue) }} }} schedulerで実⾏

Slide 13

Slide 13 text

前提の説明: RxJavaの例 class ViewModel( private val api: Api = Api(), private val scheduler: Scheduler = Schedulers.io() ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { api.fetchPersons() .subscribeOn(scheduler) .subscribe(mutablePersons::postValue) }} }} 結果をpostValueして、後はLiveDataに任せる

Slide 14

Slide 14 text

置き換えていこう

Slide 15

Slide 15 text

実際のコードだと同じSingleなメソッドを
 いくつものところから⾒ていたりする 7JFX 7JFX.PEFM "QJ LiveData> 7JFX 7JFX.PEFM LiveData> Single> ⼀つだけ置き換えできない suspend fun List

Slide 16

Slide 16 text

kotlinx-coroutines-rx2 で変換できる

Slide 17

Slide 17 text

kotlinx-coroutines-rx2で 変換する 7JFX 7JFX.PEFM "QJ Single> LiveData> 7JFX 7JFX.PEFM LiveData> Single> single.await()

Slide 18

Slide 18 text

kotlinx-coroutines-rx2で 変換する class ViewModel( private val api: Api = Api(), private val coroutineContext: CoroutineContext = CommonPool ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { launch(coroutineContext) { val persons = api.fetchPersons().await() mutablePersons.postValue(persons) }} }} }}

Slide 19

Slide 19 text

kotlinx-coroutines-rx2で 変換する class ViewModel( private val api: Api = Api(), private val coroutineContext: CoroutineContext = CommonPool ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { launch(coroutineContext) { val persons = api.fetchPersons().await() mutablePersons.postValue(persons) }} }} }} Coroutines起動

Slide 20

Slide 20 text

kotlinx-coroutines-rx2で 変換する class ViewModel( private val api: Api = Api(), private val coroutineContext: CoroutineContext = CommonPool ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { launch(coroutineContext) { val persons = api.fetchPersons().await() mutablePersons.postValue(persons) }} }} }} CoroutineContextとSchedulerは似たようなもの

Slide 21

Slide 21 text

kotlinx-coroutines-rx2で 変換する class ViewModel( private val api: Api = Api(), private val coroutineContext: CoroutineContext = CommonPool ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { launch(coroutineContext) { val persons = api.fetchPersons().await() mutablePersons.postValue(persons) }} }} }} Singleを中断関数に変換できる そして普通にListが取得できる

Slide 22

Slide 22 text

kotlinx-coroutines-rx2で 変換する class ViewModel( private val api: Api = Api(), private val coroutineContext: CoroutineContext = CommonPool ) { private val mutablePersons = MutableLiveData>() val persons: LiveData> = mutablePersons fun onCreate() { launch(coroutineContext) { val persons = api.fetchPersons().await() mutablePersons.postValue(persons) }} }} }} あとは同じようにLiveDataに流すだけ

Slide 23

Slide 23 text

いけそう!

Slide 24

Slide 24 text

実際にプロダクションに 導⼊していきたい!

Slide 25

Slide 25 text

実際にプロダクションに 導⼊していくには テストとか ライフサイクルとか エラーハンドリングとか必要

Slide 26

Slide 26 text

• テスト • エラーハンドリング • ライフサイクル • RxJavaのスレッドとの競合 実際にプロダクションに 導⼊していこう! → Qiita 『RxJavaを使っている既存アプリに Kotlin Coroutinesを導⼊しよう』にて!

Slide 27

Slide 27 text

• https://github.com/ takahirom/rxjava-2-kotlion- coroutines • いい感じにモジュール分かれ ていて、テストもあります サンプルコードもあります

Slide 28

Slide 28 text

要はRxJava1 -> RxJava2 の置き換えと⼀緒

Slide 29

Slide 29 text

Kotlin かわいい