Open5
【Android】whenLifecycle / whenStarted / whenResumed
WhenLifecycle.kt
というファイルが追加されたことを知った。
whenLifecycle
は特定のライフサイクル状態になったら引数で指定したラムダが実行される。
@Composable
private fun whenLifecycle(
state: State,
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
onState: () -> Unit,
): () -> Unit {
require(state != State.DESTROYED) {
"Target state is not allowed to be `Lifecycle.State.DESTROYED` because Compose disposes " +
"of the composition before `Lifecycle.Event.ON_DESTROY` observers are invoked."
}
return {
if (lifecycleOwner.lifecycle.currentState == state) {
onState()
}
}
}
whenLifecycle
はプライベートメソッドになっており、パブリックなメソッドとして whenStarted
と whenResumed
がある。
@Composable
fun whenStarted(
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
onStarted: () -> Unit,
): () -> Unit = whenLifecycle(State.STARTED, lifecycleOwner, onStarted)
@Composable
fun whenResumed(
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
onResumed: () -> Unit,
): () -> Unit = whenLifecycle(State.RESUMED, lifecycleOwner, onResumed)
用途としてはコメントに記載してあるようにクリック時や画面遷移時に Start, Resume 状態を保証したい場合に使える。
MyComposable(
onClick = whenStarted {
// Do something on clicks, if and only if, the lifecycle state is RESUMED
}
)
composable(...) { entry: NavBackStackEntry ->
...,
Screen1(
navigateToScreen = whenResumed {
navController.navigate("screen2")
},
先日 Navigation Compose で画面を戻る際に二重タップされて画面遷移がおかしくなる不具合があったため、まさにこれが使えそう。
あとは例えばタップを契機にして Fragment を表示する場合にこの対応を入れておけば、onSaveInstanceState が呼び出された後に Fragment を呼び出してクラッシュしてしまうといったことも防げそう。