Upgrade to Pro — share decks privately, control downloads, hide ads and more …

もう迷わないCoroutines 〜suspend funとChannelとFlow〜

nyafunta9858
December 10, 2022

もう迷わないCoroutines 〜suspend funとChannelとFlow〜

Kotlin1.3でstableになったCoroutinesは今では1.6となり、Androidアプリ開発においてはFirst Class Coroutines Supportとされてから3年が経過しました。私達のチームでも導入されており、もはやなくてはならない存在になったと感じています。
そんなCoroutinesですが、suspend function、Flow、Channel、使い分けられていますか?BroadcastChannelとMutableSharedFlowのどちらを使ったらいいか迷ったりしてませんか?

このセッションでは、kotlinx.coroutinesの最新バージョンをベースにCoroutinesの基本的な使い方を改めて抑えつつ、なんとなくで使っていたChannelやFlowなどをシーンに合わせて選択できるようになることを目指します。

nyafunta9858

December 10, 2022
Tweet

More Decks by nyafunta9858

Other Decks in Programming

Transcript

  1. 小林 慶弘 (Yoshihiro Kobayashi) a.k.a nyafunta9858 • Mobile Engineer @

    Money Forward,Inc. • 趣味:ガジェット集め、ゲーム、カメラ etc…
  2. 本セッションについて 本セッションの内容 • kotlinx.coroutines ver.1.6.4 • Kotlin Coroutinesのキホンをおさらい • suspend関数・Flow・Channelの特徴を整理

    • 利用事例のご紹介・ご提案 目標 • 実装に詰まったときの足掛かりになる • 設計・実装の検討・議論の種となる • これから始めるひとが調査・検討する際の取っ掛かりとなる
  3. コルーチンのキホン コルーチンの基本(起動) • CoroutineScopeからCoroutine Builderで起動 • 中断可能な処理(suspend関数)はCoroutineScope内で呼び出し可能 コルーチンの基本(終了) • CoroutineScope

    / CoroutineContext(コルーチンの動作に関する情報を持つ ) / Jobからキャ ンセル可能 • CoroutineScopeはライフサイクルに合わせて自動キャンセル可能 ◦ e.g. AAC ViewModelのviewModelScope
  4. コルーチンのキホン • Kotlin コルーチンを 理解しよう - Speaker Deck • Kotlin

    コルーチンを 理解しよう 2019 - KotlinFest2019 - - Speaker Deck
  5. Flowの特徴 • 複数の値を受信 • Flow / SharedFlow / StateFlowの3種 ◦

    Flow:Cold ◦ SharedFlow / StateFlow:Hot • Hot Flowは完了しない
  6. • 複数の値を受信 • Flow / SharedFlow / StateFlowの3種 ◦ Flow:Cold

    ◦ SharedFlow / StateFlow:Hot • Hot Flowは完了しない Flowの特徴
  7. ← 購読開始して初めて実行される • 複数の値を受信 • Flow / SharedFlow / StateFlowの3種

    ◦ Flow:Cold ◦ SharedFlow / StateFlow:Hot • Hot Flowは完了しない Flowの特徴
  8. ← 生成時からアクティブ • 複数の値を受信 • Flow / SharedFlow / StateFlowの3種

    ◦ Flow:Cold ◦ SharedFlow / StateFlow:Hot • Hot Flowは完了しない Flowの特徴
  9. Flow • collectで継続する値の購読 • single / first / lastなどの単一での値取得 SharedFlow

    / StateFlow • キャッシュされた値の取得 値の取得 ↑ collectから再開時に実行される 並行実行される ネストが減って見やすい
  10. Flow • collectで継続する値の購読 • single / first / lastなどの単一での値取得 SharedFlow

    / StateFlow • キャッシュされた値の取得 値の取得 ← 再開され...る? ↑ 再開の見通しがたつ
  11. Flow • collectで継続する値の購読 • single / first / lastなどの単一での値取得 SharedFlow

    / StateFlow • キャッシュされた値の取得 値の取得 ← 再開され...る? ↑ 再開の見通しがたつ
  12. Flow • collectで継続する値の購読 • single / first / lastなどの単一での値取得 SharedFlow

    / StateFlow • キャッシュされた値の取得 値の取得 ← 再開され...る? ↑ 再開の見通しがたつ
  13. Flow • collectで継続する値の購読 • single / first / lastなどの単一での値取得 SharedFlow

    / StateFlow • キャッシュされた値の取得 値の取得 ← 再開され...る? ↑ 再開の見通しがたつ collect1 0 collect1 1 collect1 2 collect1 3 collect2 0 collect2 1 collect2 2 collect2 3 collect1 4 collect2 4 collect1 5 collect2 5 collect1 6 collect2 6 : replayCacheから配信
  14. Flow • collectで継続する値の購読 • single / first / lastなどの単一での値取得 SharedFlow

    / StateFlow • キャッシュされた値の取得 値の取得 ← 再開され...る? ↑ 再開の見通しがたつ
  15. Flow • collectで継続する値の購読 • single / first / lastなどの単一での値取得 SharedFlow

    / StateFlow • キャッシュされた値の取得 値の取得 定義はいるが valueをwrapしてるのみ
  16. 値の発行 Flow Builder • flow / flowOf / callbackFlow /

    channelFlow Extension • asFlow / asSharedFlow / asStateFlow • sharedIn / stateIn Factory • MutableSharedFlow / MutableStateFlow
  17. Flow Builder • flow / flowOf / callbackFlow / channelFlow

    Extension • asFlow / asSharedFlow / asStateFlow • sharedIn / stateIn Factory • MutableSharedFlow / MutableStateFlow 値の発行
  18. Flow Builder • flow / flowOf / callbackFlow / channelFlow

    Extension • asFlow / asSharedFlow / asStateFlow • sharedIn / stateIn Factory • MutableSharedFlow / MutableStateFlow 値の発行
  19. Flow Builder • flow / flowOf / callbackFlow / channelFlow

    Extension • asFlow / asSharedFlow / asStateFlow • sharedIn / stateIn Factory • MutableSharedFlow / MutableStateFlow 値の発行
  20. 特徴 • 複数の値を送受信可能 • 送信のSendChannel、受信のReceiveChannel • Channelは生成時から値を保持可能な Hot Channel •

    配信された値は消費される channel1 0 channel2 1 channel1 2 channel2 3 channel1 4 channel2 5 channel1 6 channel2 7 channel1 8 channel2 9 消費されるため それぞれに配信されない
  21. 値の取得 • consumeEachで継続する値の購読 • Operatorのchainは不可 • receive / receiveCatchingなどで単一での値取得 •

    Flowとして購読するExtensionあり いずれも同じ処理 要素はfor文から渡ってきている
  22. 配信値 取得方法 配信方法 終了 その他 suspend fun 単一の値(型) 呼び出し ・suspendキーワード

    ・suspend ラムダ ・suspendCancellationCoroutine / suspendCoroutine ・コルーチンのキャンセルに準拠 Flow Data Stream ・collect Flow Builder ・flow ・flowOf ・callbackFlow ・channelFlow etc ・コルーチンのキャンセルに準拠 ・送信側のclose ・Cold Flow  - Flow ・Hot Flow  - SharedFlow / StateFlow  - 一対多 ・Snapshot  - replayCache (SharedFlow)  - value (StateFlow) 単一の値(型) ・first ・last ・toList etc Extension ・asFlow ・asSharedFlow ・asStateFlow etc Snapshot ・replayCache ・value Factory ・MutableSharedFlow ・MutableStateFlow Channel Data Stream 単一の値(型) ・consumeEach Channel Factory ・Channel ・コルーチンのキャンセルに準拠 ・ReceiveChannel.cancel ・SendChannel.close ・Hot Channel ・一対一 - 一度の発行で値は消費 ・値を配信するための仕組み - actor 単一の値(型) ・receive ・receiveCatching etc Channel Builder ・actor ・producer ここまでのまとめ
  23. Case.3 通信処理の置き換え But what if we don’t need either concurrency

    or synchronization, but need just non-blocking streams of data? We did not have a type for that until recently, so welcome Kotlin Flow type that is available for preview starting from kotlinx.coroutines version 1.2.0-alpha-2: https://elizarov.medium.com/cold-flows-hot-channels-d74769805f9
  24. 全体を通してまとめ 配信値 取得方法 配信方法 終了 その他 suspend fun 単一の値(型) 呼び出し

    ・suspendキーワード ・suspend ラムダ ・suspendCancellationCoroutine / suspendCoroutine ・kotlinx-coroutines:reactive modulesサポート ・コルーチンのキャンセルに準拠 Flow Data Stream ・collect Flow Builder ・flow ・flowOf ・callbackFlow:コールバック向き ・channelFlow:複数コルーチン向き ・reactive modulesサポート etc ・コルーチンのキャンセルに準拠 ・送信側のclose ・Cold Flow  - Flow:同期不要な複数値 ・Hot Flow  - SharedFlow / StateFlow  - 一対多 ・Snapshot  - replayCache (SharedFlow)  - value (StateFlow) 単一の値(型) ・first ・last ・toList etc Extension ・asFlow ・asSharedFlow ・asStateFlow ・reactive modulesサポート etc Snapshot ・replayCache ・value Factory ・MutableSharedFlow ・MutableStateFlow Channel Data Stream 単一の値(型) ・consumeEach Channel Factory ・Channel ・コルーチンのキャンセルに準拠 ・ReceiveChannel.cancel ・SendChannel.close ・Hot Channel ・一対一 - 一度の発行で値は消費 ・値を配信するための仕組み - actor 単一の値(型) ・receive ・receiveCatching etc Channel Builder ・actor:受け付ける値上限を指定 ・producer
  25. 参考 • Kotlin コルーチンを 理解しよう - Speaker Deck • Kotlin

    コルーチンを 理解しよう 2019 - KotlinFest2019 - - Speaker Deck • 5分でわかるKotlin Coroutines Flow - Speaker Deck • Cold flows, hot channels. Kotlin coroutines were missing a… | by Roman Elizarov • Reactive Streams and Kotlin Flows | by Roman Elizarov | Medium • https://youtrack.jetbrains.com/issue/KTIJ-16542/ • Kotlin/kotlinx.coroutines • SharedFlow last() never returns · Issue #3275 · Kotlin/kotlinx.coroutines · GitHub • Flow builder does not cooperate for cancellation · Issue #2000 · Kotlin/kotlinx.coroutines · GitHub • https://github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/ • https://reactivex.io/documentation/ko/operators/backpressure.html • Coroutines guide | Kotlin • Asynchronous Flow | Kotlin • https://kotlinlang.org/docs/channels.html • Shared mutable state and concurrency | Kotlin • Android での Kotlin コルーチン | Android デベロッパー • Android での Kotlin Flow | Android デベロッパー • StateFlow and SharedFlow | Android Developers • 完全に理解した気になるKotlin Coroutines - Qiita • Coroutines reactive moduleで今日からKotlin Coroutinesに入門する - Qiita • Hot and cold data sources • SharedFlow and StateFlow • Cancellation and timeouts | Kotlin • 詳細CoroutineContext | by Kenji Abe • kotlin coroutinesのFlow, SharedFlow, StateFlowを整理する - Blog - Mori Atsushi • kotlin coroutinesのStateFlowのドキュメントを読み込む - Blog - Mori Atsushi