はじめに
Jetpack Composeの導入、進んでいますか?
新規プロダクトなら「フルCompose」で気持ちよく開発できますが、歴史あるプロダクトや大規模なアプリでは、まだまだActivityやFragmentの遷移を残しつつ、
Viewの中身だけComposeに置き換えるというハイブリッドな構成で戦っている方も多いのではないでしょうか。
そんなActivity/FragmentとComposeが共存するハイブリッドな開発環境において、
「Activityのコードを減らしたい」「将来の完全Compose移行を考慮したい」という動機から、
SharedFlowをComposable内で処理しようとして
失敗してしまった経験を共有します。
やってしまった失敗実装
ViewModelからのワンショットイベント(SharedFlow)をComposable側で受け取るため、以下のような拡張関数を自作しました。
// Composable
@Composable
@SuppressLint("ComposableNaming")
inline fun SharedFlow.collectWithLifecycle(
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
minActiveState: Lifecycle.State = Lifecycle.State.CREATED,
collector: FlowCollector
) {
LaunchedEffect(Unit) {
lifecycleOwner.lifecycle.repeatOnLifecycle(minActiveState) {
this@collectWithLifecycle.collect(collector)
}
}
}実装イメージ(真似しないで)
これを使えば、Composable関数側でイベントハンドリングが完結するように見えます。
// Composable
@Composable
fun HogeScreen( // ActivityのsetContentで呼び出すComposable関数
viewModel: HogeViewModel = hiltViewModel(),
onNavigate: () -> Unit // Activity側ではstartActivityを呼び出す想定
) {
// ViewModelのイベントを監視
viewModel.navigateEvent.collectWithLifecycle {
// イベントが来たらコールバックを実行(Activity遷移など)
onNavigate()
}
// ... UIの実装
}一見、とてもスマートに見えました。Activityのコードは減り、ロジックはComposableに寄る。
しかし、このアプローチは大きな間違いでした。
なぜ失敗だったのか
結論から言うと、SharedFlowだと監視外のイベントが喪失してしまうためです。
SharedFlowは、監視前に発火したイベントを拾えません。
(replayを使えば拾えますが、replay = 1などでキャッシュを持たせると、今度は「画面回転しただけでイベントが発火する」というバグを生み出します。)
なので基本的に画面遷移直後に「トースト表示イベント」や「画面遷移のイベント」を発火したい。
という要件があっても
ライフサイクルが非アクティブ(Resumedじゃない)状態だとイベントを拾えません。
Android開発公式も「UIレイヤーでのワンショットイベント監視」はアンチパターンとしています。
https://proandroiddev.com/android-one-off-events-approaches-evolution-anti-patterns-add887cd0250
Composeは「宣言的UI」です。「イベントが起きたらどうする」ではなく、
「今の状態(State)はどうあるべきか」を記述するフレームワークです。
どうすべきだったか
今回の失敗を経て、2つの解決策にたどり着きました。
Googleが推奨する「State管理」への移行か、あるいは「Activityでの監視」に戻るかです。
…
記事の続きは下のURLをクリック!
http://rightcode.co.jp/blogs/54309
エンジニア積極採用中です!
現在、WEBエンジニア、モバイルエンジニア、デザイナー、営業などを積極採用中です!
採用ページはこちら:https://rightcode.co.jp/recruit
社員の声や社風などを知りたい方はこちら:https://rightcode.co.jp/blogs?category=life
フリーランスエンジニア大募集中!
現在、「WEBエンジニア」「フロントエンジニア」「データサイエンティスト」など、様々な職種のフリーランスエンジニア様を募集中です。まずは以下よりお気軽にご応募ください!
採用ページはこちら:https://itanken.com/register
社長と一杯飲みながらお話しませんか?(転職者向け)
特設ページはこちら: https://rightcode.co.jp/gohan-sake-president-talk
もっとワクワクしたいあなたへ
現在、ライトコードでは「WEBエンジニア」「モバイルエンジニア」「ゲームエンジニア」、「デザイナー」「WEBディレクター」「営業」などを積極採用中です!
ライトコードは技術力に定評のある受託開発をメインにしているIT企業です。
有名WEBサービスやアプリの受託開発などの企画、開発案件が目白押しの状況です。
- もっと大きなことに挑戦したい!
- エンジニアとしてもっと成長したい!
- モダンな技術に触れたい!
現状に満足していない方は、まずは、エンジニアとしても第一線を走り続ける弊社代表と気軽にお話してみませんか?
ネット上では、ちょっとユルそうな会社に感じると思いますが(笑)、
実は技術力に定評があり、沢山の実績を残している会社ということをお伝えしたいと思っております。
- ライトコードの魅力を知っていただきたい!
- 社風や文化なども知っていただきたい!
- 技術に対して熱意のある方に入社していただきたい!
一度、【Wantedly内の弊社ページ】や【コーポレートサイト】をのぞいてみてください。
Wantedly:https://www.wantedly.com/companies/rightcode
コーポレート:https://rightcode.co.jp/