🧬
【Android】Fragment内に表示されるComposeのライフサイクルを調べる
概要
Fragment内に表示されているComposeのlifecycleがどのような振る舞いをするのか確認する。
経緯
Jetpack compose化のリファクタリングをしている中で、FragmentのonResumeでViewModelのデータを更新する処理があり、composeだとどのタイミングになるのだろうと悩んだので調査しました。
画面構成
MainActivity は3つのフラグメントを持ち、これらはボトムナビゲーションバーを使って切り替えることができます。
このフラグメントの中で、HomeFragmentはUIコンポーネントにJetpack Composeを使用しています
New Project > Bottom Navigation Views Activity
を少しだけ変更して使用しました。
コード
実装箇所
- HomeFragmentの表示をComposeで実装
- HomeFragmentとHomeScreen(Compose)のLifecycle eventsにLogを追加
Fragment
class HomeFragment : Fragment() {
private val TAG = "Fragment"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate")
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
Log.d(TAG, "onCreateView")
return ComposeView(requireContext()).apply {
setContent {
MaterialTheme {
HomeScreen()
}
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d(TAG, "onViewCreated")
}
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart")
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume")
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause")
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop")
}
override fun onDestroyView() {
super.onDestroyView()
Log.d(TAG, "onDestroyView")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy")
}
override fun onDetach() {
super.onDetach()
Log.d(TAG, "onDetach")
}
}
Compose
@Composable
fun HomeScreen() {
val TAG = "Compose"
LaunchedEffect(Unit) {
Log.d(TAG, "LaunchedEffect")
}
DisposableEffect(Unit) {
Log.d(TAG, "DisposableEffect")
onDispose {
Log.d(TAG, "DisposableEffect: onDispose")
}
}
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = "This is home screen",
color = Color.White
)
}
}
より詳しい実装を確認したい場合は以下のリポジトリーから
Log結果
※ 見やすいように一部省略しています
// アプリ起動 Fragmentを表示
2025-01-11 18:30:46.196 19420-19420 Fragment D onCreate
2025-01-11 18:30:46.199 19420-19420 Fragment D onCreateView
2025-01-11 18:30:46.202 19420-19420 Fragment D onViewCreated
2025-01-11 18:30:46.245 19420-19420 Fragment D onStart
2025-01-11 18:30:46.250 19420-19420 Fragment D onResume
2025-01-11 18:30:46.353 19420-19420 Compose D DisposableEffect
2025-01-11 18:30:46.461 19420-19420 Compose D LaunchedEffect
// 他のタブに切り替える
2025-01-11 18:31:09.906 19420-19420 Fragment D onPause
2025-01-11 18:31:09.907 19420-19420 Fragment D onStop
2025-01-11 18:31:10.074 19420-19420 Compose D DisposableEffect: onDispose
2025-01-11 18:31:10.076 19420-19420 Fragment D onDestroyView
// Homeタブに戻す
2025-01-11 18:31:18.772 19420-19420 Fragment D onCreateView
2025-01-11 18:31:18.779 19420-19420 Fragment D onViewCreated
2025-01-11 18:31:18.790 19420-19420 Compose D DisposableEffect
2025-01-11 18:31:18.791 19420-19420 Fragment D onStart
2025-01-11 18:31:18.794 19420-19420 Compose D LaunchedEffect
2025-01-11 18:31:18.948 19420-19420 Fragment D onResume
結果
onCreateViewのたびにComposeは作り直されるので、onResumeでのデータの再取得はLaunchedEffect(Unit)
でやればOK!
Discussion