Tech/App-Android

[Android.]Ch2-4. remember vs rememberSaveable

JSJH._. 2026. 3. 24. 09:15

[Android] Ch2-4. remember vs rememberSaveable

1. 개요 및 기본 형식

@Composable
fun RememberExample() {
    // remember: 통상적인 Recomposition 시에만 값 유지
    var count1 by remember { mutableStateOf(0) }
    // rememberSaveable: 화면 회전, 시스템에 의한 제약 프로세스 재시작 시에도 유지
    var count2 by rememberSaveable { mutableStateOf(0) }
}
  • 두 함수 모두 Recomposition 과정에서 UI State 손실을 방지합니다.
  • rememberSaveable의 경우 Bundle 복원 매커니즘을 지원하여, Activity 재생성/프로세스 일시정지 단계에서도 라이프사이클을 뛰어넘는 영속화 기능을 제공합니다.

2. 주요 구성 및 차이점

1) remember

  • Recomposition 시 유지: 관련된 Composable 함수가 자동 호출 및 갱신되어도 내부에 캐시된 이전 값을 방어하며 유지시킵니다.
  • 화면 회전 시 초기화: 모바일 디바이스의 회전 등으로 인해 최상단 Activity가 Destruction 이후 Regeneration 단계에 돌입하면 내부 값이 모두 무효화되고 초기화됩니다.
  • 프로세스 재시작 시 초기화: OS 메모리 확보 등을 위해 앱이 백그라운드에서 강제 종료되었다가 복귀하면 데이터가 손실됩니다.

2) rememberSaveable

  • Recomposition 시 유지: 기본적인 뷰 업데이트 사이클에서의 보존 기능은 동일합니다.
  • 화면 회전 시 유지: Activity Regeneration 과정 중에도 자동 객체 직렬화/역직렬화를 기반으로 이전 값들을 정상 복구합니다.
  • 프로세스 재시작 시 유지: 백그라운드에서의 예기치 않은 종료 이후 구동될 때도 저장 값이 안전하게 복구됩니다.
  • 제약 사항: SavedState(Bundle) 객체에 저장 가능한 허용 범위 구조체 타입(Int, String, Boolean 등 원시 및 일부 선형 데이터)에 대해서만 작동을 보장합니다.

3. 활용 방식

1) remember 활용 패턴

화면 전환 등으로 데이터가 초기화되어도 서비스 경험에 심각한 치명도를 발생시키지 않는, 온전한 임시 UI 상태 제어에 최적화된 방법입니다.

@Composable
fun RememberExample() {
    var count by remember { mutableStateOf(0) }

    Button(onClick = { count++ }) {
        Text("Count: $count")
    }
    // 디바이스 가로 모드 진입 시 즉각 0으로 값 손실 및 초기화됨
}

2) rememberSaveable 활용 패턴

입력 도중 유실될 경우 사용자 측면의 피로도가 극도로 높은 핵심 상태 정보 유지에 적용합니다.

@Composable
fun RememberSaveableExample() {
    var count by rememberSaveable { mutableStateOf(0) }

    Button(onClick = { count++ }) {
        Text("Count: $count")
    }
    // 화면을 가로 및 세로로 회전하여도 현재까지 반영된 카운팅 횟수가 안전하게 복원됨
}

3) 사용자 입력 데이터 보존의 예

장문의 텍스트 입력 폼 등은 유실 스트레스가 높으므로 필수적으로 Saveable을 구성 대상별로 각각 적용합니다.

@Composable
fun UserInputForm() {
    var name by rememberSaveable { mutableStateOf("") }
    var email by rememberSaveable { mutableStateOf("") }

    Column {
        TextField(
            value = name,
            onValueChange = { name = it },
            label = { Text("이름 입력 영역") }
        )
        TextField(
            value = email,
            onValueChange = { email = it },
            label = { Text("이메일 입력 영역") }
        )
    }
    // 데이터 보존 안정성 확보
}

4) 임시 뷰 컴포넌트 상태 배제법 (remember 사용 권장안)

드롭다운 탭 메뉴 확장, 다이얼로그의 임시 표출 여부는 굳이 Bundle 직렬화 딜레이와 비용을 낭비하면서까지 보존할 타겟이 아닙니다.

@Composable
fun DropdownExample() {
    var expanded by remember { mutableStateOf(false) }

    Box {
        Button(onClick = { expanded = true }) {
            Text("메뉴 리스트 펼치기")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            // DropDown 리스트 뷰 구축
        }
    }
    // 화면 회전 이후 닫혀 있는 상태(초기 상태)가 되어도 크게 무방함
}

4. 부가 설명

1) 사용 기준점 종합 가이드

  • remember를 사용해야 하는 경우:
    • 다이얼로그, 드롭다운 창 등의 단순 UI 확장 표출 상태
    • 임시로 로드되는 애니메이션 상태
    • 오버헤드 방지 및 속도 최적화가 필요한 대칭성 UI
  • rememberSaveable을 사용해야 하는 경우:
    • 입력 텍스트 폼, 패스워드 폼 데이터
    • 결제창에서의 유저 선택 체크 여부
    • 기타 디바이스 화면 회전이나 전화 수신 등 태스크 전환에 강건히 대응해야 하는 필수 비즈니스 로직 정보

2) Bundle 컴포넌트 특성

  • Android OS 코어에서 데이터 전달 및 단발성 보존을 할당하는 핵심 매커니즘 컴포넌트입니다.
  • 객체 직렬화가 동반되므로 원시 타입 파라미터가 아닌 커스텀 개발 모델 객체 등 특이 구조의 데이터를 보존할 때는 별도로 Saveable 인터페이스 설정 작업을 거쳐야 합니다.

3) 성능 팩터 비교

  • remember: 힙 메모리 세션에 단발성 보관. 지연 및 과부하가 없어 상대적으로 성능 속도가 우위에 있습니다.
  • rememberSaveable: OS가 시스템 내부에 상태를 안전하게 직렬화 및 적재하느라 다소간의 IO 딜레이가 발생합니다.
  • 다만 모던 모바일 디바이스 성능 체계 내에서는 이 두 프로세스 간의 체감 지연 차이는 일반적인 용례 내에서 완전히 무시 가능한 수준입니다.

'Tech > App-Android' 카테고리의 다른 글

[Android].Ch2-5. Material Design 3  (0) 2026.03.24
[Android].Ch2-3. 상태 호이스팅  (0) 2026.03.24
[Android].Ch2-2.TextField  (0) 2026.03.23
[Android].Ch2-1.LazyColumn & LazyRow  (0) 2026.03.23
[Android].Ch1-5.이벤트 처리  (0) 2026.03.20