
SavedStateHandle은 Android ViewModel에서 화면 상태를 복원하기 위한 작은 저장 공간입니다. 특히 화면 회전과 process death를 구분해서 이해해야 언제 필요한지 선명해집니다.
많이 헷갈리는 지점은 ViewModel이 이미 화면 회전을 버티는데 왜 SavedStateHandle이 필요하냐는 질문입니다. 답은 간단합니다. ViewModel은 configuration change에는 강하지만, system-initiated process death까지 장기 저장해 주는 도구는 아닙니다.

SavedStateHandle을 이해하려면 두 상황을 나눠야 한다
Android 공식 상태 저장 문서는 configuration change와 system-initiated process death를 나누어 상태 저장 전략을 설명합니다.
이 주제는 기존의 rememberSaveable과 SavedStateHandle 차이 글과 이어서 보면 더 이해하기 쉽습니다.
첫 번째는 화면 회전 같은 configuration change입니다. Activity나 Fragment가 다시 만들어져도 ViewModel은 유지될 수 있습니다. 이때는 ViewModel 안의 UI state가 그대로 남아 있으므로 SavedStateHandle이 꼭 필요하지 않을 수 있습니다.
두 번째는 시스템이 앱 프로세스를 종료했다가 나중에 복원하는 상황입니다. 이때 ViewModel 인스턴스는 메모리에 남아 있지 않습니다. 화면을 다시 만들려면 어떤 데이터를 다시 불러와야 하는지 알 수 있는 작은 단서가 필요합니다.
- 검색 화면의 query 문자열
- 상세 화면의 itemId
- 탭이나 필터의 선택값
- 사용자가 입력 중이던 짧은 폼 값
ViewModel과 SavedStateHandle의 역할 차이
ViewModel은 화면에 필요한 상태를 메모리에서 관리합니다. 네트워크 결과, DB에서 읽어온 목록, 화면 로딩 상태처럼 UI를 그리는 데 필요한 값을 담기 좋습니다.
SavedStateHandle은 그 상태 전체를 저장하는 곳이 아닙니다. 다시 로드할 수 있는 최소 단서를 저장하는 곳에 가깝습니다. 예를 들어 상품 상세 화면에서는 상품 객체 전체보다 productId를 저장하고, 복원 뒤 productId로 다시 조회하는 방식이 더 안전합니다.
class DetailViewModel(
private val savedStateHandle: SavedStateHandle,
private val repository: ProductRepository
) : ViewModel() {
private val productId: String = checkNotNull(savedStateHandle["productId"])
val uiState: StateFlow<DetailUiState> =
repository.observeProduct(productId)
.map { DetailUiState(product = it) }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), DetailUiState())
}rememberSaveable과는 무엇이 다를까
Compose의 rememberSaveable은 composable 안의 저장 가능한 UI 상태를 보존하는 데 유용합니다. 예를 들어 텍스트 필드의 임시 입력값이나 접힘/펼침 상태처럼 UI 가까이에 있는 값에 잘 맞습니다.
반면 SavedStateHandle은 ViewModel이 복원에 필요한 값을 들고 있어야 할 때 자연스럽습니다. 특히 navigation argument와 연결되거나, ViewModel 로직이 그 값을 기준으로 데이터를 다시 불러와야 한다면 SavedStateHandle 쪽이 더 낫습니다.
- UI 안에서만 쓰는 작은 상태: rememberSaveable
- ViewModel 로직이 다시 로드해야 하는 단서: SavedStateHandle
- 앱의 실제 데이터 원본: Room, DataStore, 서버, 파일 저장소
SavedStateHandle에 넣지 말아야 할 것
SavedStateHandle은 편리하지만 모든 상태를 넣는 저장소가 아닙니다. 큰 리스트, 이미지, 복잡한 도메인 객체, 장기간 유지해야 할 데이터는 적절하지 않습니다. Android 공식 문서도 saved state 계열 API를 장기 저장소로 보지 말고, UI 상태를 다시 로드하는 데 필요한 작은 데이터에 쓰는 방향을 안내합니다.
- 복원에 꼭 필요한 최소값인지 확인한다
- 그 값으로 원본 데이터를 다시 불러올 수 있는지 본다
- 크거나 복잡한 객체라면 저장하지 않는다
- 장기 보존이 필요하면 DB나 DataStore를 쓴다
정리
SavedStateHandle은 ViewModel을 대체하는 저장소가 아닙니다. ViewModel이 사라진 뒤 화면을 다시 만들기 위한 작은 단서를 남기는 도구입니다.
화면 회전만 걱정한다면 ViewModel로 충분한 경우가 많습니다. 하지만 process death 이후에도 사용자가 보던 화면을 적절히 복원해야 한다면 SavedStateHandle을 설계에 포함하는 것이 좋습니다.