SavedStateHandle이란?

Bluewave·2025년 6월 22일

안드로이드

목록 보기
12/14
post-thumbnail

Jetpack Compose에서 상태 기억하는 법

루틴 생성 기능 만들면서 제일 고민됐던 게 화면 이동할 때 상태를 어떻게 유지하느냐였다.
예를 들면, 제스처 고르고, 기기 상태 설정하고, 아이콘 고르고... 이게 다 다른 화면에서 이뤄지는데,
이걸 다 ViewModel이 기억하고 있어야 한다는 얘기.

그래서 사용한 게 바로 SavedStateHandle.


SavedStateHandle

  • ViewModel이 상태를 기억할 수 있게 해주는 도구
  • 뷰가 죽거나, 화면이 다시 만들어져도 데이터를 복원할 수 있음
  • Navigation Compose 쓸 때 화면 간 안전하게 데이터 넘기는 용도로 딱 좋음
  • Bundle 비슷한데 ViewModel 친화형 버전 느낌

언제 사용하는가

  • 화면 전환해서 돌아왔을 때 값이 날아가지 않게 하고 싶을 때
  • 뷰가 recreate 됐을 때도 상태 그대로 유지하고 싶을 때
  • Navigation에서 SafeArgs 쓰기 애매할 때

in LUMOS

LUMOS 루틴 생성은 흐름이 이렇게 되어 있다:

제스처 선택 / 루틴 제목 입력 / 이모지 선택 → 기기 설정 → 상태 직렬화 → 저장

이 모든 과정에서 여러 화면을 거치게 되는데,
이때 필요한 상태값을 SavedStateHandle로 전달하거나, 받아왔다.

상태용도
gestureId어떤 제스처 썼는지 기억해둬야 루틴 저장 가능
commandDeviceJson기기 설정한 값, JSON으로 넘겨야 함
routineId수정 모드일 때 어떤 루틴인지 알아야 함
iconId유저가 선택한 아이콘 정보

예를 들면,
기기 설정 프리뷰 다 하고 돌아왔을 때, commandDeviceJson을 이전 화면의 SavedStateHandle에 저장해두면,
루틴 생성 ViewModel이 그걸 꺼내서 바로 상태 반영 가능함.


코드로 보면

// ViewModel에서
class RoutineCreateViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle
) : ViewModel() {
    val gestureId: String? = savedStateHandle["gestureId"]
    val commandDeviceJson: String? = savedStateHandle["commandDeviceJson"]
}
// 돌아가기 전, 상태를 이전 화면에 넘길 때
navController.previousBackStackEntry
    ?.savedStateHandle
    ?.set("commandDeviceJson", device.toJson())

왜 굳이 이걸 썼냐면

  • Intent나 SafeArgs보다 구조가 단순하고 ViewModel 친화적임
  • 프로세스 죽었다 살아나도 상태 복구 가능
  • Navigation Compose랑 함께 사용하기 좋음
  • 코드에서 상태 흐름이 명확하게 드러남

정리

항목설명
목적화면 간 상태 전달 + 복원
장점생명주기에 덜 휘둘림, ViewModel 안에서 관리
적용루틴 생성 흐름 (제스처, 기기 상태, 아이콘 등)
방식화면 진입 시 가져오거나, 이전 화면에 상태 세팅
profile
Developer's Logbook

0개의 댓글