The Compose application is designed to be used in a single-activity architecture with no fragments.
You can still have multiple activities or fragments and use setContent
in each of them, but in this case the transfer of data between activities falls on your shoulders. Use this approach if you're adding new Compose screens to an existing application built the old way.
But with Compose, it's much easier to do all the navigation within a single activity using Compose Navigation. Much less code, better performance due to no unnecessary code layers, easy to transfer data, etc.
To work with the view lifecycle, check out compose side-effects:
LaunchedEffect
can be used to execute an action when the view appears. It also runs on a coroutine context that is bound to the current composable: you can easily run suspend functions, and when the view disappears from view hierarchy - the coroutine will be canceled.
DisposableEffect
can be used to subscribe to/unsubscribe from callbacks.
When you rotate the screen, all effects will restart no matter which key you passed.
@Composable
fun MainScreen(navController: NavController) {
LaunchedEffect(Unit) {
println("LaunchedEffect: entered main")
var i = 0
// Just an example of coroutines usage
// don't use this way to track screen disappearance
// DisposableEffect is better for this
try {
while (true) {
delay(1000)
println("LaunchedEffect: ${i++} sec passed")
}
} catch (cancel: CancellationException) {
println("LaunchedEffect: job cancelled")
}
}
DisposableEffect(Unit) {
println("DisposableEffect: entered main")
onDispose {
println("DisposableEffect: exited main")
}
}
}
Also note that in both cases, and in many other cases in compose, you pass key
to these functions. This helps compose understand when the value should be recomputed. In my example it is Unit
, which means that it won't change until the view is gone. But if you create a remember
value, use another dynamic value from the view model, or pass another argument to composable, you can pass it as a key
, this will cancel the current LaunchedEffect
job and call onDispose
for DisposableEffect
, and your job will be restarted with the updated key
value. You can pass as many keys as you want.
Read more about the state in Compose in documentation.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…