flowを使い始め、もはやAndroid開発にはflowが必要不可欠になってきました。そんな中、以前紹介したStateFlowに加えて、SharedFlowが1.4.0-M1から登場しました。複雑に感じますが、実はかなり整理されており、以前より使いやすくなっていると思っています。今回は、Flow、SharedFlow、StateFlowの概要に関して紹介し、各々の詳細に関しては別途まとめたいと思います。型の関係を確認するFlowまず、Flowの定義はこのようになっています。今回は型のみを重視するため、一旦メンバに関しては考慮しません。T>SharedFlow次にSharedFlowです。Flow<T>Flowを継承していることがわかると思います。書き換え可能なSharedFlowである、MutableSharedFlowの定義はこうです。FlowCollector<T>SharedFlowを継承しており、またFlowCollectorという型も継承しています。FlowCollectorはこのような定義になっています。T)}FlowのBuilderの中にも使われているので、実はよく使っていると思います。Flow<T>StateFlow次に、以前も紹介したStateFlowの定義です。SharedFlow<T>以前紹介した際はFlowを継承していましたが、SharedFlowの継承に変わっています。こちらもMutableなMutableStateFlowがあります。MutableSharedFlow<T>StateFlowだけでなく、MutableSharedFlowも継承していますね。これらを、ベン図で表すとこのような関係性になります。SharedFlowもStateFlowもFlowの一種であり、StateFlowはSharedFlowに内包されています。これらの関係性を理解した上で、それぞれの機能についてみていきましょう。それぞれの機能についてFlowまず最初に、StateFlowでもSharedFlowでもない、通常のflowの挙動について確認したいと思います。channelFlow等を使って作ることができます。streamと言われるものです。streamはsubscribeするまで動作せず、subscribeした際に毎回動作します。表示され、最初に渡したlambda式がsubscribeの回数分呼ばれていることがわかります。emit!emit!onEach1:1onEach2:1この仕様は、ときに便利ですが、builderやoperator内で重たい処理をしたいときに不便になることもあります。streamのため、flowに対して直接値を流すことはできません。streamとして登場したのがSharedFlowです。SharedFlowの作り方として、MutableSharedFlowとshareInがあります。MutableSharedFlowMutableSharedFlowは、このように使うことができます。処理が終わるまでちょっと待つ}先程のflowとは違い、flowに対して直接emitすることができます。scopeが必要なことに注意してください。実行すると、以下のような結果が得られます。onEach2:1onEach1:1onEach2:2onEach1:2簡単に複数箇所でsubscribe可能なstreamを作成することができました。MutableSharedFlowには、このように3つの引数がありますが、それぞれの内容に関しては今回は省略させてください。MutableSharedFlow<T>shareInSharedFlowを作る、もう一つの方法、shareInに関して紹介します。shareInは通常のFlowをSharedFlowに変換するoperatorです。SharedFlow<T>shareInを使うことで、flowの説明のときに話した、重たい処理の問題を解決することができます。一度しか呼ばれてないことがわかるでしょうか。これは、SharedFlowが下流の複数subscriber間で値を共有しているためです。replayの引数に関する説明は今回は省略します。StateFlow続いてStateFlowです。こちらは、状態保持のための特別なSharedFlowとして認識してもらえれば大丈夫です。MutableStateFlowかstateInで作成ができます。今回は、MutableStateFlowの方を紹介し、stateInの方は省略します。MutableStateFlowこのように使うことができます。処理が終わるまでちょっと待つonEach1:0onEach1:1onEach2:1onEach2:2onEach1:2ほとんどSharedFlowと同じように扱えますが、いくつか異なる点があります。launchInしたタイミングで直近の値が1件流れてきます。scopeがなくても問題ありません。同じ値は流れない、連続して値が変更されると、最後の値のみ流れてくる、といった特徴があります。1は流れてこないあくまでも状態保持のflowとして設計されているのがわかると思います。streamとしてchannelを使っていたと思います。今回追加された変更により、BroadcastChannelはSharedFlowに、ConflatedBroadcastChannelはStateFlowに置き換えが可能です。公式にSharedFlowとStateFlowがstableになり次第、BroadcastChannelとConflatedBroadcastChannelはdeprecatedになると告知されています。この方針は変わらないと思われるので、そろそろ乗り換えを検討したほうが良さそうです。複数subscriber間で値を共有する,subscribe時に直前の値が流れる,同じ値を流さない,連続した値は最後だけ流す使い分けとしては、イベントを扱いたいならSharedFlow、状態を扱いたいならStateFlowを使い、streamの変換等はFlowを使って行うことになると思います。flowで流れてきたものを、shareInを使ってSharedFlowに変換することで、ストリームの共通化を行うことができます。Coroutinesの解説本をZennにて販売しています。詳しく学びたい方は、こちらも合わせて確認してみて下さい。AtsushiTopWorksPhotosBlogContact。