Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
イベントをどう管理するか
Search
mikan
December 06, 2024
Technology
3
280
イベントをどう管理するか
【祝!50回】Shibuya.apk #50
https://shibuya-apk.connpass.com/event/336398/
mikan
December 06, 2024
Tweet
Share
More Decks by mikan
See All by mikan
Kotlin Multiplatform 始めました
mikanichinose
1
120
Web APIをなぜつくるのか
mikanichinose
0
1.8k
ライブラリでしかお目にかかれない珍しい実装
mikanichinose
2
400
Strong Skipping Mode によってrecompositionはどう変わったのか
mikanichinose
0
240
Modeling UiEvent
mikanichinose
0
51
UIの構成要素に関する考察
mikanichinose
0
52
再考: 監視可能オブジェクト
mikanichinose
0
65
マルチモジュール懐疑派だったかつての自分に送る マルチモジュールの効能
mikanichinose
0
210
書評: 単体テストの考え方/使い方
mikanichinose
0
270
Other Decks in Technology
See All in Technology
エンジニアリング価値を黒字化する バリューベース戦略を用いた 技術戦略策定の道のり
kzkmaeda
6
2.7k
LINEギフトにおけるバックエンド開発
lycorptech_jp
PRO
0
280
AWSを活用したIoTにおけるセキュリティ対策のご紹介
kwskyk
0
350
AWS Well-Architected Frameworkで学ぶAmazon ECSのセキュリティ対策
umekou
2
140
【Findy】「正しく」失敗できる チームの作り方 〜リアルな事例から紐解く失敗を恐れない組織とは〜 / A team that can fail correctly by findy
i35_267
5
890
OCI Success Journey OCIの何が評価されてる?疑問に答える事例セミナー(2025年2月実施)
oracle4engineer
PRO
2
160
技術スタックだけじゃない、業務ドメイン知識のオンボーディングも同じくらいの量が必要な話
niftycorp
PRO
0
100
いまからでも遅くない!コンテナでWebアプリを動かしてみよう!コンテナハンズオン編
nomu
0
150
【内製開発Summit 2025】イオンスマートテクノロジーの内製化組織の作り方/In-house-development-summit-AST
aeonpeople
2
670
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
19k
30→150人のエンジニア組織拡大に伴うアジャイル文化を醸成する役割と取り組みの変化
nagata03
0
180
OPENLOGI Company Profile
hr01
0
60k
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
366
25k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
RailsConf 2023
tenderlove
29
1k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
133
33k
Producing Creativity
orderedlist
PRO
344
40k
Fireside Chat
paigeccino
34
3.2k
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.5k
How to train your dragon (web standard)
notwaldorf
91
5.9k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Transcript
イベントをどう管理するか Shibuya.apk #50 mikan(一瀬喜弘)
自己紹介 object Mikan { val name = 一瀬喜弘 val from
= 長崎 val company = カラビナテクノロジー株式会社 val work = Engineer.Android val volunteer = DroidKaigi val hobby = listOf( "漫画", "アニメ", "ゲーム", "折り紙", "OSS開発・コントリビュート", ) }
今日お話しする内容
Channel vs. SharedFlow vs. StateFlow エラーや 通信結果などの イベントを どこで 管理するのか
結論 エラーや 通信結果などの イベントを どこで 管理すべきか?
それぞれの メリデメを 把握したうえで 適当な ものを 選んでください
どれを 使うかは 所詮手段でしかないです 取り扱おうと している イベントの 重要度だったり、 どう ハンドリングされるかを きちんと
把握しないと 適切な ホルダーは 選べません
これから メリデメを 紹介するので、 適した 手段を 検討できるようになって もらえれば 幸いです
イベントとは
イベントとは ユーザー操作によってUI側から発生し、ViewModelに 伝達したい情報
None
けど ViewModelから UIに イベントを 送信したい ときも ありますよね
ex. 1. 通信が完了したら画面遷移する 2. 通信が失敗したらエラーダイアログを表示する 3. SharedPreferencesからデータを削除したらトーストを表示す る
None
ViewModelから UIに イベントを 伝達する ためにはなにかしら データホルダーが 必要に なる
Channel? SharedFlow? StateFlow? 戦争が始まる
それぞれについて実装方法をみ ていきます
Channel データの持ち方 イベントの発火 // ViewModel private val _message = Channel<String>()
val message = _message.receiveAsFlow() viewModelScope.launch { _message.send("message...") }
Channel イベントの消費 // Fragment viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.message.collect {
showSnackBar(it) } } }
Channel イベントの消費 // Compose val lifecycle = LocalLifecycleOwner.current.lifecycle LaunchedEffect(Unit) {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.message.collect { showSnackBar(it) } } }
Channel メリット collectorがいない間に発生したイベントをバッファリングできる(demo) デメリット イベントの 消費中に coroutine が キャンセルされたら どうしますか?
(demo)
Channel メリット collectorがいない間に発生したイベントをバッファリングできる(demo) デメリット イベントの 消費中に coroutine が キャンセルされたら どうしますか?
(demo) → バッファリングの挙動とバックグラウンド時のキャンセルが絡み合うとイベン トハンドリングの振る舞いがどんどん予測困難になる
SharedFlow データの持ち方 イベントの発火 // ViewModel private val _message = MutableSharedFlow<String>()
val message = _message.asSharedFlow() viewModelScope.launch { _message.emit("message...") }
SharedFlow イベントの消費 Channelのときと同じ // Fragment viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.message.collect
{ showSnackBar(it) } } }
SharedFlow イベントの消費 Channelのときと同じ // Compose val lifecycle = LocalLifecycleOwner.current.lifecycle LaunchedEffect(Unit)
{ lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.message.collect { showSnackBar(it) } } }
SharedFlow メリット デメリットに目を瞑れば、シンプルにイベントを実装できる デメリット collectorがいないとイベントは垂れ流されてロストする(demo) ex. 構成変更が発生するとUIが再構成されるので一瞬collectorがいなくなっ て、その間に発生したイベントはロストする イベントを発火するときに、subscriptionCountが1以上になっていること をチェックすることで回避可能だが。
。 replayCacheをいくらか設けて回避するという手もある
SharedFlow メリットともデメリットとも取れる collectorが複数いた場合に、1つのイベントが同時に複数回消費されることに なる(demo) ハンドリングが同じ場合は期待しない挙動になる可能性がある ハンドリングが異なる場合は有用な可能性がある このことを考慮して設計してあるならヨシ → Channelだと複数のcollectorに同じ情報を伝達できない
StateFlow データの持ち方 イベントの発火 // ViewModel // 初期値が必要だがイベントに初期値などないのでnullで表現する private val _message
= MutableStateFlow<String?>(null) val message = _message.asStateFlow() _message.value = "message..."
StateFlow // Fragment viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.message.collect { if
(it != null) { showSnackBar(it) // イベントをハンドリングしたあとは明示的に消費する viewModel.consumeMessage() } } } } // ViewModel fun consumeMessage() { _message.value = null }
StateFlow // Compose val message by viewModel.message.collectAsStateWithLifecycle() LaunchedEffect(message) { message?.let
{ onMessageReceive(it) viewModel.consumeMessage() } }
StateFlow メリット イベント処理中にcollectorがキャンセルされてたとしても、復帰後に最新のイ ベントは残っているので再ハンドリング可能 デメリット イベントの消費をプログラミングしないといけない 明示的にイベントを消し込み イベントを消費したとは? 論理的には消費したが、物理的に消費してない状態が成立する(demo)
まとめ Channel ⭕ トーストにメッセージを表示するなどの単純なイベントに向いている ⭕ collect前にイベントが発火する可能性がある場合に向いている ❌ イベントが消失する可能性があるので、重要なイベントには向いてない SharedFlow ⭕
トーストにメッセージを表示するなどの単純なイベントに向いている ⭕ バッファリングとか考えなくてよいのでシンプル ❌ イベントが消失する可能性があるので、重要なイベントには向いてない StateFlow ❌ 単純なイベントについては過度 ⭕ イベントの処理を保証しないといけない場合は向いている ⭕ 重要なイベントに向いている
ご清聴ありがとうございました