영어 데일리

컴포즈에서 ViewModel 생명주기 마스터하기

현욱 정리장 2025. 3. 10. 14:38

컴포즈는 안드로이드 개발을 간소화하며, ViewModel과의 통합을 통해 상태 관리를 더욱 원활하고 생명주기를 인식하게 합니다. 

이 기사에서는 컴포즈에서 뷰모델이 어떻게 동작하는지 깊게 알아보고, 뷰모델의 생명주기 연관된 부분을 설명하며, 개념을 확실히 다지기 위해 실제 사용사례를 설명하겠습니다. 

이 글은 모두에게 무료입니다. 만약 너가 구독을 활성화 하고 싶다면 여기를 클릭하세요. 아닐 경우 쭉 읽어주세요.

 

컴포즈에서 뷰모델 생명주기 이해하기 

컴포즈에서 뷰모델은 기본적으로 생명주기를 의식하는 방식으로 UI관련된 데이터를 저장하고 관리하는데에 사용합니다. 이것은 화면 회전과 같은 구성 변경에도 유지되며, 연결된 생명 주기 소유자가 소멸될때 자동으로 제거됩니다. 

 

핵심

1. 생명주기 인식

뷰모델은 해당 컴포저블의 부모 (액티비티나 네비게이션 대상) 의 생명주기에 연결됩니다.

2. 자동 제거

컴포저블이나 생명주기 소유자가 제거 될 때에 뷰모델은 자동으로 클리어 됩니다. 이는 효율적인 리소스 관리를 보장합니다.

3. 컴포즈와의 통합

컴포즈의 viewModel() 함수는, ViewModel이 올바르게 생명주기 소유자의 범위 지정 되도록 보장합니다.

 

실제 사용사례, 카운터 앱 

컴포즈에서 viewmodel 생명주기를 설명하는 카운터앱을 구현해보겠습니다. 이 앱은 다음과같습니다

  • 매 초마다 카운터가 업데이트됩니다.
  • 화면 사이에 네비게이션을 허용하며, 스크린이 제거될때 뷰모델 생명주기가 어떻게 동작하는지 확인합니다. 
  • onCleared() 함수내에 초기화 로직이 포함되어있습니다.

뷰모델 생성

CouterViewModel은 카운터 상태를 관리하며 매초 카운터를 증가시키는 코루틴을 포함하고 있습니다. 이것은 뷰모델이 초기화될때 리소스 초기화를 하는 방법에 대해 설명합니다.

 

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class CounterViewModel : ViewModel() {
    private val _counter = MutableStateFlow(0)
    val counter: StateFlow<Int> = _counter

    init {
        // Simulate periodic updates
        viewModelScope.launch {
            while (true) {
                delay(1000)
                _counter.value += 1
            }
        }
    }

    override
    fun onCleared() {
        super.onCleared()
        println("ViewModel cleared: Resources cleaned up!")
    }

}

 

컴포저블 UI 빌드하기

CounterScreen은 viewModel()함수를 사용해 ConterViewModel객체를 가져옵니다. 이것은 카운터 상태를 관찰하고, UI에 따라 업데이트됩니다. 

import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.gaurav.shimmereffectdemo.CounterViewModel

@Composable
fun CounterScreen(onNavigateBack: () -> Unit) {
    val counterViewModel: CounterViewModel = viewModel()
    val count by counterViewModel.counter.collectAsState()

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(text = "Count: $count", style = MaterialTheme.typography.headlineMedium)
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = onNavigateBack) {
            Text("Back")
        }
    }
}



네비게이션 셋업 

네비게이션은 CounterViewModel 생명 주기가 네비게이션 그래프에 연결되도록 보장합니다. 유저가 다른 화면으로 이동할때, ViewModel은 제거됩니다.

import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.gaurav.shimmereffectdemo.component.CounterScreen

@Composable
fun AppNavigation(){
    val navController = rememberNavController()

    NavHost(navController, startDestination = "counter") {
        composable("counter") {
            CounterScreen(onNavigateBack = { navController.popBackStack() })
        }
    }
}


모든 내용을 종합하여 하나로 연결하기

위의 구성요소들을 통합하고 실행하세요. 화면들을 이동해보면서, ViewModel 상태 관리가 어떻게되는지, 어떻게 제거되는지 관찰해보세요.

 

생명주기 행동 분석

1. CounterScreen이 활성화 될 때 

  • CounterViewModel 객체가 생성됩니다.
  • Counter 상태가 매초마다 업데이트 됩니다.

2. 뒤로 네비게이션 될 때 

  • NavBackStackEntry가 파괴됩니다.
  • 연결된 ViewModel이 제거되며, onCleared 함수가 호출됩니다. 

연습 팁

1. 적절한 viewModel() 사용: 항상 viewModel() 함수를 사용하여 viewmodel이 적절한 생명주기에 연결되도록 보장하세요.

2. 메모리 누수 피하기: onCleared()내에서 리소스들을 초기화함으로써 메모리릭을 방지하세요.

3. 생명주기 테스트: onCleared() 메소드에 로그를 추가하여 viewmodel의 생명 주기 동작을 확인하세요.

4. 네비게이션 활용: 제트백 네비게이션을 사용해 생명주기 친화적인 화면 전환을 사용하세요. 

 

결론

컴포즈와 뷰모델의 결합은, 효율적인 빌드와 생명주기 친화적인 안드로이드 앱을 최소한의 보일러플레이트로 만들 수 있습니다. 

위 예제는 ViewModel이 상태관리를 단순화하면서도 적절한 리소스를 정리하는 보장하는 방법을 보여줍니다. 이 가이드를 통해 이제 컴포즈에서 뷰머델 생명주기 관리를 마스터할 준비가 되었습니다. 

 

https://medium.com/towardsdev/mastering-viewmodel-lifecycle-in-jetpack-compose-a-complete-guide-with-example-64e82db6c07d

 

Mastering ViewModel Lifecycle in Jetpack Compose: A Complete Guide with Example

Jetpack Compose simplifies UI development in Android, and its integration with ViewModel makes state management more seamless and…

towardsdev.com

 

 

 

기타

to cement the concepts 개념을 확실히 다질 수 있도록 

conscious 의식하는 

navigate away 다른곳으로 이동하다 

leverage 활용하다 

illustrates 설명하다