* 개인적으로 테스트해본 코드들을 정리하는 포스팅이며 꾸준히 업데이트할 예정입니다.
* 잘못된 부분 지적이나 새로운 의견 제시는 언제나 환영입니다! :)
Compose를 사용하다보면 if문이나 when문에 따라서 다른 Composable이 나타나도록 하고 싶을 때가 있습니다. 이 때 코드가 어떤 순서로 실행되는지가 궁금하여 직접 테스트해 보았습니다.
먼저 새 프로젝트를 만들고 아래와 같이 setContent에서 MainScreen Composable을 호출했습니다.
setContent {
ComposableIfTestTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
MainScreen()
}
}
}
MainScreen Composable의 코드는 다음과 같습니다.
@Composable
fun MainScreen() {
val contentNum = remember { mutableStateOf(0) }
Column() {
Button(
onClick = {
contentNum.value = (contentNum.value + 1) % 4
}
) {
Text(
text = "Button",
color = Color(0xffffffff)
)
}
when (contentNum.value) {
0 -> {
Content1()
}
1 -> {
Content2()
}
2 -> {
Content3()
}
else -> {
Content4()
}
}
}
}
버튼을 클릭하면 contentNum의 값이 1씩 커지고 contentNum의 값에 따라 Content1, Content2, Content3, Content4 Composable이 호출됩니다.
각 Content Composable은 다음과 같습니다. 예전부터 궁금했던 DisposableEffect, LaunchedEffect도 추가하여 테스트해보았습니다. Content2, 3, 4에서는 숫자만 다르고 나머지 코드는 동일하게 테스트하였습니다.
@Composable
fun Content1() {
Log.e("Content1", "Content1")
DisposableEffect(true) {
Log.e("Content1", "Content1 - DisposableEffect")
onDispose {
Log.e("Content1", "Content1 - onDispose")
}
}
LaunchedEffect(true) {
Log.e("Content1", "Content1 - LaunchedEffect")
}
Text(
text = "Content1"
)
}
처음 앱이 실행되면 아래의 로그가 출력됩니다.
Content1
Content1 - DisposableEffect
Content1 - LaunchedEffect
여기까진 일단 예상대로 출력됐습니다.
이제 버튼을 한번 눌러보았습니다.
Content2
Content1 - onDispose
Content2 - DisposableEffect
Content2 - LaunchedEffect
예상과 다르게 Content2가 먼저 출력되고 Content1의 onDispose가 출력됩니다.
버튼을 한번 더 눌러도 아래와 같이 Content3이 출력된 후 Content2의 onDispose가 출력됩니다.
Content3
Content2 - onDispose
Content3 - DisposableEffect
Content3 - LaunchedEffect
음 이건 몰랐던 사실이네요. 다음부턴 이 부분을 고려하여 코드를 작성해야될 것 같습니다.
그냥 혹시나 해서 아래와 같이 DisposableEffect와 LaunchedEffect의 위치를 바꾸고 다시 실행해봤습니다.
@Composable
fun Content3() {
Log.e("Content3", "Content3")
LaunchedEffect(true) {
Log.e("Content3", "Content3 - LaunchedEffect")
}
DisposableEffect(true) {
Log.e("Content3", "Content3 - DisposableEffect")
onDispose {
Log.e("Content3", "Content3 - onDispose")
}
}
Text(
text = "Content3"
)
}
근데 다음과 같이 DisposableEffect의 로그가 먼저 찍히는걸 확인했습니다.
Content2
Content1 - onDispose
Content2 - DisposableEffect
Content2 - LaunchedEffect
LaunchedEffect를 먼저쓴다고 LaunchedEffect의 코드가 먼저 실행되는건 아니네요. 이거도 잘 고려해야겠습니다.