[mvvm] 뷰모델 지피티 물음 정리2

말랑돌·2025년 8월 13일

안드로이드 학습

목록 보기
14/17

ViewModelStoreOwner는 무엇이며, backStackEntry을 viewmodel에 넣는 이유는 무엇이고, AppNavHost에서는 viewModel이 정의되지 않았는데 어떻게 사용하는 것이며, viewModel의 생성자에는 backStackEntry를 받는 부분이 없는 거 같은데 어떻게 저 코드가 가능하지 궁금하다

Jetpack Compose에서 ViewModel의 생명주기는 ViewModelStoreOwner에 의해 결정됩니다.
즉, ViewModel 자체가 화면이 아니라 소유자(owner) 에 묶여서 살아있다가, owner가 사라질 때 같이 파괴됩니다.


1. ViewModel의 생명주기 기본 원리

  • ViewModel은 화면의 생명주기(Lifecycle) 와는 조금 다릅니다.

  • 실제로는 ViewModelStoreOwner(예: Activity, NavBackStackEntry)에 묶여서 유지됩니다.

  • 일반적인 경우:

    • Activity에 묶으면 → Activity가 파괴될 때까지 ViewModel이 유지됩니다.
    • NavBackStackEntry에 묶으면 → 해당 화면이 Navigation back stack에서 제거될 때 ViewModel이 파괴됩니다.

2. 예시로 보는 차이

// Activity 범위 ViewModel
val vm = viewModel<MainViewModel>()
// → Activity가 살아있는 동안 계속 유지됨.
// → 다른 화면 전환 후에도 같은 인스턴스 사용 가능.

// Navigation backStackEntry 범위 ViewModel
val vm = viewModel<MainViewModel>(backStackEntry = navBackStackEntry)
// → 이 backStackEntry가 pop될 때 ViewModel이 파괴됨.
// → 화면 전환 시 다른 인스턴스로 교체 가능.

3. backStackEntry를 사용하는 이유

  • Compose Navigation에서는 각 화면이 NavBackStackEntry라는 owner를 가짐.
  • viewModel(backStackEntry)로 지정하면
    → 화면 전환 시에도 backStackEntry가 남아 있는 한 ViewModel 상태를 유지.
  • 뒤로 가기(pop)로 backStackEntry가 제거되면
    ViewModel.onCleared() 호출 후 메모리에서 제거됨.

4. AppNavHost에서 ViewModel이 안 보이는데 동작하는 이유

  • Compose Navigation의 composable(route) { backStackEntry -> ... } 구문에서
    backStackEntry가 곧 ViewModelStoreOwner 역할을 합니다.
  • viewModel() 함수는 현재 Composition의 LocalViewModelStoreOwner를 자동으로 가져와 사용합니다.
  • 즉, factory나 owner를 명시하지 않아도 현재 화면의 backStackEntry에 자동 연결됩니다.

5. ViewModel 생명주기 요약

ViewModel 범위소유자(ViewModelStoreOwner)파괴 시점
Activity 범위ActivityActivity 종료 시
Navigation 범위NavBackStackEntrybackStackEntry pop 시
Fragment 범위FragmentFragment 종료 시

📌 핵심

  • ViewModel의 수명은 UI 컴포넌트의 생명주기가 아니라 ViewModelStoreOwner에 의해 관리됩니다.
  • Navigation을 쓰면 화면마다 독립된 생명주기를 가질 수 있어서, 같은 Activity 내에서도 화면별 ViewModel 유지/삭제가 가능합니다.

0개의 댓글