RxJavaを使っている 既存アプリに Kotlin Coroutinesを導入しよう

7166bc2cbc462ab5fd1987a76d0fe709?s=47 takahirom
August 25, 2018
670

RxJavaを使っている 既存アプリに Kotlin Coroutinesを導入しよう

7166bc2cbc462ab5fd1987a76d0fe709?s=128

takahirom

August 25, 2018
Tweet

Transcript

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

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

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

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

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

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

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

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

    suspend List<Person> LiveData<List<Person>>
  9. 前提の説明: RxJavaの例 class ViewModel( private val api: Api = Api(),

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

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

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

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

    private val scheduler: Scheduler = Schedulers.io() ) { private val mutablePersons = MutableLiveData<List<Person>>() val persons: LiveData<List<Person>> = mutablePersons fun onCreate() { api.fetchPersons() .subscribeOn(scheduler) .subscribe(mutablePersons::postValue) }} }} 結果をpostValueして、後はLiveDataに任せる
  14. 置き換えていこう

  15. 実際のコードだと同じSingleなメソッドを
 いくつものところから⾒ていたりする 7JFX 7JFX.PEFM "QJ LiveData<List<Person>> 7JFX 7JFX.PEFM LiveData<List<Person>> Single<List<Person>>

    ⼀つだけ置き換えできない suspend fun List<Person>
  16. kotlinx-coroutines-rx2 で変換できる

  17. kotlinx-coroutines-rx2で 変換する 7JFX 7JFX.PEFM "QJ Single<List<Person>> LiveData<List<Person>> 7JFX 7JFX.PEFM LiveData<List<Person>>

    Single<List<Person>> single.await()
  18. kotlinx-coroutines-rx2で 変換する class ViewModel( private val api: Api = Api(),

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

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

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

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

    private val coroutineContext: CoroutineContext = CommonPool ) { private val mutablePersons = MutableLiveData<List<Person>>() val persons: LiveData<List<Person>> = mutablePersons fun onCreate() { launch(coroutineContext) { val persons = api.fetchPersons().await() mutablePersons.postValue(persons) }} }} }} あとは同じようにLiveDataに流すだけ
  23. いけそう!

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

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

  26. • テスト • エラーハンドリング • ライフサイクル • RxJavaのスレッドとの競合 実際にプロダクションに 導⼊していこう!

    → Qiita 『RxJavaを使っている既存アプリに Kotlin Coroutinesを導⼊しよう』にて!
  27. • https://github.com/ takahirom/rxjava-2-kotlion- coroutines • いい感じにモジュール分かれ ていて、テストもあります サンプルコードもあります

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

  29. Kotlin かわいい