Jetpack Compose의 UI 생명주기와 상태 추적을 관리하는 시스템입니다.
- Compose는 선언형 UI → “UI = 상태(state)의 함수”
- Compose Runtime은 내부적으로 상태 변경을 감지하고, 필요한 부분만 재구성(Recomposition) 합니다.
remember나mutableStateOf()같은 것은 Compose Runtime이 상태를 추적하기 위한 장치예요.
즉, Runtime은 “UI를 그려주고, 상태를 기억하고, 상태 변화에 맞춰 UI를 다시 그리는 관리자”입니다.
비동기 코드의 실행 범위를 정의하는 “작업 영역”입니다.
val scope = rememberCoroutineScope()
scope.launch {
// 이 블록 안은 별도의 코루틴으로 실행
}
| 개념 | 설명 |
|---|---|
| Coroutine | 가벼운 스레드처럼 동작하는 비동기 작업 단위 |
| CoroutineScope | 여러 코루틴을 담고 관리하는 “컨테이너” |
| launch | 새 코루틴을 실행하고, Scope가 살아있는 동안 유지됨 |
| cancel() | Scope를 종료하면 내부 코루틴도 함께 종료됨 |
rememberCoroutineScope()란?Compose에 특화된 CoroutineScope로,
현재 컴포저블이 런타임에 활성 상태일 동안만 살아 있는 코루틴 스코프를 제공합니다.
즉:
val bottomSheetActionScope = rememberCoroutineScope()
✅ 이 스코프는 Compose Runtime이 자동으로 관리합니다.
UI가 사라지면 코루틴도 정리돼서 메모리 누수나 비정상 실행이 발생하지 않아요.
val bottomSheetState = rememberModalBottomSheetState()
val bottomSheetActionScope = rememberCoroutineScope()
if (bottomSheetState.isVisible) {
BottomSheetScreen(bottomSheetState) {
bottomSheetActionScope.launch {
bottomSheetState.hide()
}
}
}
이 구조를 세분화해서 보면 👇
rememberModalBottomSheetState()rememberCoroutineScope()launch { bottomSheetState.hide() }hide() 함수는 suspend function (일시 중단 가능 함수)이므로,launch 필요)이건 매우 정확한 표현이에요.
Compose의 런타임은 다음과 같은 원리로 동작합니다:
| 상태 변화 | Compose 런타임 동작 | CoroutineScope 동작 |
|---|---|---|
모달시트가 보임 (isVisible = true) | 해당 UI 트리(컴포저블)가 활성화됨 | rememberCoroutineScope()가 활성 상태 |
모달시트가 닫힘 (isVisible = false) | BottomSheetScreen 컴포저블이 Composition Tree에서 제거됨 | Scope 자동 cancel() → 코루틴도 함께 종료됨 |
즉,
💡 즉, “모달시트가 닫히면 코루틴을 끊는다”는 건
Compose Runtime이 해당 코루틴 스코프를 자동으로 정리(cancellation)한다는 뜻이에요.
| 구성 요소 | 역할 | 관리 주체 |
|---|---|---|
remember | 상태를 런타임에 저장 | Compose Runtime |
mutableStateOf | 상태 변화를 감지해 재구성 트리거 | Compose Runtime |
rememberCoroutineScope() | 코루틴 스코프를 Compose 수명주기에 맞게 관리 | Compose Runtime |
launch { ... } | 비동기 실행 블록 | CoroutineScope |
hide() / show() | suspend 함수 → 코루틴 내에서만 실행 가능 | Coroutine |
[Compose Runtime]
│
├─ rememberModalBottomSheetState()
│ ↓ (상태 저장 및 추적)
│
├─ rememberCoroutineScope()
│ ↓ (UI 수명에 맞는 코루틴 스코프 생성)
│
└─ launch { bottomSheetState.hide() }
↓
suspend fun hide() → BottomSheetState 애니메이션 비동기 처리
↓
BottomSheet 사라짐 → Composition Tree에서 제거
↓
rememberCoroutineScope() 자동 cancel()
| 항목 | 설명 |
|---|---|
| 코루틴은 Compose 런타임이 제어하는 생명주기 내에서 작동한다. | UI가 사라지면 Scope도 함께 cancel됨 |
rememberCoroutineScope()는 UI 생명주기 의존형 스코프이다. | UI와 함께 생성되고 파괴됨 |
| Suspend 함수는 반드시 코루틴 내에서 호출해야 한다. | 예: bottomSheetState.show(), hide() |
| 런타임이 코루틴을 직접 관리한다. | 불필요한 코루틴이 남지 않도록 자동 정리 |
“BottomSheet가 떠 있는 동안만 CoroutineScope가 유지되고,
닫히면 Compose Runtime이 자동으로 Scope를 정리한다.”
val sheetState = rememberModalBottomSheetState()
val sheetScope = rememberCoroutineScope()
BottomSheetScreen(sheetState) {
sheetScope.launch {
sheetState.hide() // suspend 함수 → 코루틴 내에서 실행
}
}
✔️ 코루틴은 런타임이 UI 생명주기에 맞춰 관리
✔️ hide() 수행 도중 UI가 사라지면 → 런타임이 Scope를 cancel → 코루틴 즉시 종료
Compose Runtime은 상태와 UI 생명주기를 관리하고,
rememberCoroutineScope()는 그 생명주기에 맞춰 자동으로 생성·소멸되는 코루틴 실행 컨테이너이다.
즉, BottomSheet가 닫히면 Scope가 cancel되어 코루틴도 함께 종료된다.
Compose Runtime은 무대 감독, CoroutineScope는 조명 팀과 같아요.
무대(컴포저블)가 열리면 조명이 켜지고 (코루틴 실행),
무대가 닫히면 감독(Runtime)이 조명 팀에게 “끄자(cancel)” 하고 조명을 종료시킵니다.
즉, 무대가 사라지면(모달시트 닫힘) 코루틴도 함께 끝납니다.