프론트엔드 입문이나 프로젝트 세팅에서 가장 중요한거는 네비게이션 세팅이라고 생각한다.
2025년 현재 안드로이드 컴포즈에서 가장 기본적인 네비게이션에 필요한 개념들은 다음과 같다.
- NavController
- NavBackStackEntry
- SavedHandleState
- ViewModel
📌 ViewModel과 SavedStateHandle의 관계
1. ViewModel은 기본적으로 프로세스 종료 시 유지되지 않음
• ViewModel은 구성 변경(Configuration Change)(예: 화면 회전) 시에도 유지되는 특징이 있다.
• 하지만, 안드로이드 시스템이 앱을 강제로 종료했다가 다시 복원하는 경우 ViewModel도 사라짐.
1. 사용자가 홈 버튼을 눌러 앱을 백그라운드로 보냄
2. 안드로이드 시스템이 메모리가 부족해서 앱 프로세스를 강제 종료함
3. 사용자가 다시 앱으로 돌아오면, 새 ViewModel이 생성됨 (이전 상태가 사라짐 ❌)
2. 프로세스 종료 후 다시 앱이 복원될 때, UI 상태를 유지해야 함
안드로이드는 이런 프로세스 종료를 대비해서 onSaveInstanceState를 제공하지만,
이 방식은 액티비티/프래그먼트에서만 사용 가능하고, ViewModel에서는 직접 접근할 수 없음.
• SavedStateHandle은 이런 문제를 해결하기 위해 도입됨.
• 즉, ViewModel에서 “프로세스 종료 후에도 유지해야 하는 데이터”를 저장하는 용도로 사용됨.
3. 비정상적인 프로세스 종료 (메모리 부족 등으로 강제 종료된 경우)
• 액티비티가 A>B>C인 상태에서 종료되었을때
• 이 경우, 안드로이드는 마지막으로 열려 있던 액티비티(C)를 복원하려고 시도함.
• 시스템이 onSaveInstanceState()를 호출해서 데이터를 저장해 놓았다면, 앱이 다시 실행될 때 C부터 시작할 가능성이 큼.
📌 savedStateHandle이 하는 일
Navigation Arguments 저장 & 복원
안드로이드에서 ViewModel은 프로세스 재시작시 파괴된다!
→ 그래서 savedStateHandle을 사용하면, 네비게이션으로 전달된 데이터를 안전하게 관리할 수 있어.
1️⃣ NavController가 savedStateHandle을 내부적으로 사용해서 네비게이션 인자를 관리
• 네비게이션으로 전달된 인자(ex: id)를 savedStateHandle에 저장
• 시스템에 의한 프로세스 종료시에도 다시 복원 가능
2️⃣ ViewModel에서 savedStateHandle을 받으면 네비게이션 인자를 가져올 수 있음
• val (id) = savedStateHandle.toRoute<NoticeDetail>()
• 이렇게 하면 id 값을 안전하게 가져올 수 있음
3️⃣ 각 화면에 ViewModel이 생성됨
• Composable 화면마다 ViewModel이 생성됨
• ViewModel은 화면 전환 시 유지되지만, 화면이 완전히 제거되면 함께 사라짐
📌 결론: 각 화면마다 ViewModel이 생기고, Navigation 인자는 savedStateHandle을 통해 관리된다!
📌 NavController는 각 화면을 NavBackStackEntry로 관리하고,
NavBackStackEntry는 내부적으로 savedStateHandle을 포함
✅ 4. 그럼 savedStateHandle은 언제 삭제될까?
✔ 현재 화면이 백스택에서 제거되면 savedStateHandle도 삭제됨
✔ 하지만 “백스택에 남아 있는 화면”의 savedStateHandle은 계속 유지됨
✔ 즉, popUpTo(A, inclusive=true) 하면 B, C의 데이터는 삭제됨!
✔ 사용자가 완전히 앱 종료시 / onFinish()시에 삭제됨!
'Android' 카테고리의 다른 글
[Android] Jetpack Compose에서 Props drilling을 피하는 패턴 (1) | 2025.04.11 |
---|---|
[Android] 선언형과 리액티브 프로그래밍을 왜 사용하는가 (0) | 2025.04.07 |
[Android] 아키텍처 정리 (1) | 2025.01.31 |