Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
イベントをどう管理するか
Search
mikan
December 06, 2024
Technology
420
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
イベントをどう管理するか
【祝!50回】Shibuya.apk #50
https://shibuya-apk.connpass.com/event/336398/
mikan
December 06, 2024
More Decks by mikan
See All by mikan
Loop Engineering これくらいでいい
mikanichinose
0
250
形式手法を使って仕様をコーディングしよう
mikanichinose
0
190
Navigation3でやりとりした画面引数をSavedStateHandleから引き出せない理由
mikanichinose
0
40
Lazy APIを使ってGradleビルド速度を改善する
mikanichinose
1
94
Navigation3でViewModelにデータを渡す方法
mikanichinose
0
770
「脳に収まるコードの書き方」を読んで学んだこと
mikanichinose
1
240
RepositoryのSSoT化
mikanichinose
0
110
Kotlin Multiplatform 始めました
mikanichinose
1
170
Web APIをなぜつくるのか
mikanichinose
0
4.4k
Other Decks in Technology
See All in Technology
パッチ更新でterraform initが落ちた日
grimoh
1
140
UniFi(ユニファイ)AIカメラの現場活用
ludicmind
1
430
その Valkey 使いこなしていますか?
onk
PRO
5
1.4k
Claude の新機能を、 出た日に触って社内に届けるまで
rfdnxbro
1
160
子育てエンジニアの可処分時間が減っても成長を諦めない戦い方
sudoakiy
6
4.6k
V8のArray.prototype.flatを最大約20倍速くするまでと、巨大OSSへの大規模コミットの道のり
riyaamemiya
0
290
無理せず続ける、子育てエンジニアの学び
codmoninc
PRO
0
830
触りたくないデータに、どう触るか AI時代のRBACアクセスガバナンス
ivry_presentationmaterials
0
260
SAENM ~Jupyterで残すPoCの試行錯誤、未来の自分と仲間を助ける記録!~
terapyon
0
110
パスキーの自動テストはどこまでいけるのか
teamlab
PRO
0
180
AIにシークレットを見せない、WSL2で安全な開発環境
yazm
0
290
USB PDを使ってスマホを労わりたい
raspython3
0
170
Featured
See All Featured
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
How STYLIGHT went responsive
nonsquared
100
6.3k
Test your architecture with Archunit
thirion
2
2.4k
Accessibility Awareness
sabderemane
1
250
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
30 Presentation Tips
portentint
PRO
1
430
Why Our Code Smells
bkeepers
PRO
340
58k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
500
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 ❌ 単純なイベントについては過度 ⭕ イベントの処理を保証しないといけない場合は向いている ⭕ 重要なイベントに向いている
ご清聴ありがとうございました