90
68

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

初学者向けKotlin Coroutines Flow

Last updated at Posted at 2020-11-16

前置き

  • 本資料は以下の方向けです
    • Flowって何だ、うめぇのか?
    • コルーチン??
    • 周りでFlow使われてるけど、サッパリわからん…
    • 1日でFlowを何となく理解したい
  • 以下の方は退屈かと思います
    • Flowを何となく理解した
    • Flowはいいぞ
    • Flow?あぁ、若い頃を思い出すな…

Kotlin Coroutine Flowとは

  • Kotlin Coroutinesの新しい非同期処理用ライブラリ
  • RxやPromiseに似た記述ができる
  • コールドストリーム!

コールドストリームとは

  • Subscribeされたら初めて動きだす、Observableなストリーム
  • ストリーム...データを連続して送り出す型
  • それ以上は、RxのHotとColdについてを参照

会社員に例えると

  • 上司(Subscriber)が社員(Observable)を監視(Subscribe)する ←語呂がいい
  • 社員は上司に状況を逐一報告(emit/send/offer)する
  • 上司はそのうち監視をやめる(Dispose)

ホットストリームな働き方

🧑‍🦰 Hotさん「さあ、上司いないけど仕事はじめようっと!」

上司に監視されなくても働き始める

🤵 上司「Hotさん、今どんな感じ?」
🧑‍🦰 Hotさん「はい、こういう状況です!」
🤵 上司「・・・なるほど」

🧑‍🦰 Hotさん「状況変わりました!」
🤵 上司「・・・なるほど」

上司が見てる間、ずっと報告を出す

🤵 上司「Hotさん、もういいよ」
🧑‍🦰 Hotさん「では、作業終了します!」

上司に止められるまで働き続ける

Hotさんは何人の上司がいてもマイペースで、頭を使う量も変わりません

コールドストリームな働き方

🧑‍🦱 Coldさん「・・・(ボーッとしている)」

上司に監視されないと働かない

🤵 上司「Coldさん、どんな感じ?」
🧑‍🦱 Coldさん「(やべ、上司だ!)今はじめますんで!…はい、こういう状況です」
🤵 上司「・・・なるほど」

🧑‍🦱 Coldさん「状況変わりました!」
🤵 上司「・・・なるほど」

上司が見てる間、ずっと報告を出す

🧑‍🦱 Coldさん「(上司いなくなったな…)作業終了します」

上司がいなくなったら自分で働くのをやめる

Coldさんは常に上司の目を気にしており、上司が2人に増えると2倍頭を使います

Hotさんの良いところと欠点

Hotさんのほうが気力に満ちて有能に見えますが、難点もあります。

  • 良いところ
    • 上司がいなくても働ける(上司以外の人も報告を見れる)
    • 上司が増えても、使うリソースは変わらない
  • 難点
    • ちゃんと止めてあげないと、必要ないときも働き続けてしまう

Coldさんの良いところと欠点

部下としては少し不安なColdさんですが、プログラムとして、必要ないときに働かないのは実は強力な利点です。

  • 良いところ
    • 必要ないときにリソースを使わない
    • 不要になったリソースを即時開放してくれる
  • 難点
    • 上司が2人に増えたら、使うリソースも2倍に増えてしまう

Kotlinでは

元々Kotlin社にはChannelというHotさんがいたが、FlowというColdさんが最近入社されました。

Flowの基本的な使い方

  • ビジネスロジックは無加工のデータを非同期に送る
CounterUseCase.kt
suspend fun countStream(): Flow<Int> = flow {
    repeat(100) { count ->
        delay(100)
        emit(count) // 0 1 2 3 4 ... 99
    }
}
  • ViewModelがデータを受け取り、表示向けに加工する
CounterViewModel.kt
val showing = MutableLiveData<String>()

fun showCountEvenNumbersSquared() {
    viewModelScope.launch(Dispatchers.Main) {
        useCase.countStream()
            .drop(1)
            .filter { it % 2 == 0 }
            .map { (it * it).toString() }
            .take(5)
            .collect { count.value = it } // 4 16 36 64 100
    }
}
  • Viewが表示する
MainActivity.kt
counterViewModel.showCountEvenNumbersSquared()
activity_main.xml
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{counterViewModel.showing}" />

全体図

View    |  ViewModel    | UseCase〜深層
-----------------------------------------------
        |               |
入力    →  Coroutine起動 → 時間のかかる処理(非同期)
          |                   |       ↓↓↓
描画  ←←←  出力データ加工 ←←← 出力データ送信(複数回)
        |               |

Flowにはオペレーターがたくさんあり、この左向き時のデータ加工に優れています。

おすすめ参考リンク

なんとなくイメージを掴んだところで、より理解が進みそうな記事をいくつか紹介します。

5分でわかるFlow

Flowの便利さを実感する

ホットストリームなFlow!?SharedFlowとStateFlowとは

ViewModelScopeの補足説明

Dispatcherの補足説明

既存アプリへのFlow導入実例

Jetpack ComposeとFlow

公式ドキュメント

あとがき

本記事の内容が、技術書典12新刊のACCESSテックブック2に収録されました!
2020年に書いた記事ですが、2022年6月現在も閲覧数がとても多く、勉強会スライドのままだと読みづらかったので、記事形式で書き直しました。
参考リンクの記事を提供してくださったみなさま、ありがとうございます。

90
68
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
90
68

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?