Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 코루틴
- DAGGER
- DI
- Retrofit
- error
- 의존성주입
- coroutine
- 안드로이드 스튜디오
- 유튜브
- ADB
- cursor
- compose
- MVVM
- 코틀린
- build
- 에러
- 안스
- 안드로이드
- hilt
- 안드로이드스튜디오
- RecyclerView
- WebView
- 스튜디오
- Kotlin
- Android
- Github
- 깃헙
- studio
- 웹뷰
- Gradle
Archives
- Today
- Total
코딩하는 일용직 노동자
LaunchedEffect, DisposableEffect, LifecycleEventEffect, LifecycleStartEffect, LifecycleResumeEffect 정리 본문
안드로이드
LaunchedEffect, DisposableEffect, LifecycleEventEffect, LifecycleStartEffect, LifecycleResumeEffect 정리
bacass 2025. 8. 10. 13:43안드로이드 Jetpack Compose에서 사용하는 주요 Effect Handler들에 대해 각각의 역할과 사용 사례를 중심으로 설명해 드릴게요.
이 Effect Handler들은 Composable 함수의 생명주기와는 별개로 실행되어야 하는 작업, 즉 \*\*Side Effect(부수 효과)\*\*를 안전하게 관리하기 위해 사용됩니다.
예를 들어 데이터베이스에 접근하거나, 네트워크 요청을 보내거나, 리스너를 등록하는 등의 작업이 여기에 해당합니다.
1. LaunchedEffect
`LaunchedEffect`는 Composable이 처음으로 화면에 그려질 때(Composition 될 때) **코루틴을 실행**하고 싶을 때 사용합니다. 가장 일반적으로 사용되는 Effect Handler 중 하나입니다.
* **핵심 개념**: Composable의 생명주기에 맞춰 시작되고, Composable이 화면에서 사라지면 자동으로 취소되는 코루틴 스코프를 제공합니다.
* **주요 사용 사례**:
* 화면 진입 시 **초기 데이터 로딩** (API 호출)
* **Snackbar나 Toast**를 한 번만 보여주고 싶을 때
* 특정 조건이 만족되었을 때 \*\*화면 이동(Navigation)\*\*을 하고 싶을 때
* **동작 방식**:
* `key`로 지정된 값이 변경될 때마다 기존 코루틴은 **취소**되고, 새로운 코루틴이 시작됩니다.
* `key`로 `true`를 사용하면 Composable이 처음 Composition 될 때 **단 한 번만** 실행됩니다.
@Composable
fun MyScreen(
scaffoldState: ScaffoldState,
shouldShowSnackbar: Boolean
) {
// shouldShowSnackbar 값이 true로 변경될 때마다 스낵바를 보여줍니다.
if (shouldShowSnackbar) {
LaunchedEffect(key1 = scaffoldState.snackbarHostState) {
scaffoldState.snackbarHostState.showSnackbar(
message = "오류가 발생했습니다.",
actionLabel = "확인"
)
}
}
}
2. DisposableEffect
`DisposableEffect`는 리소스를 할당하고, Composable이 화면에서 사라질 때 해당 \*\*리소스를 정리(clean-up)\*\*해야 하는 경우에 사용합니다.
* **핵심 개념**: `onDispose` 블록을 통해 정리 로직을 반드시 실행하도록 보장합니다.
* **주요 사용 사례**:
* `BroadcastReceiver`나 각종 콜백 **리스너를 등록하고 해제**할 때
* Android `LifecycleObserver`를 추가하고 제거할 때
* **동작 방식**:
* `DisposableEffect` 블록 안의 코드는 Composable이 Composition 될 때 실행됩니다.
* `onDispose` 블록은 Composable이 Composition에서 벗어나거나, `key`가 변경되어 Effect가 재시작될 때 호출됩니다.
@Composable
fun HomeScreen(
onStart: () -> Unit,
onStop: () -> Unit
) {
val lifecycleOwner = LocalLifecycleOwner.current
// lifecycleOwner가 변경되지 않는 한 한 번만 실행됩니다.
DisposableEffect(key1 = lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_START) {
onStart()
} else if (event == Lifecycle.Event.ON_STOP) {
onStop()
}
}
lifecycleOwner.lifecycle.addObserver(observer)
// Composable이 사라질 때 observer를 정리합니다.
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
아래의 Effect들은 Android의 `Lifecycle` 이벤트에 좀 더 특화되어 있어 코드를 간결하게 만들어 줍니다.
3. LifecycleEventEffect
`Lifecycle`의 **모든 이벤트**(`ON_CREATE`, `ON_START`, `ON_RESUME` 등)를 관찰하고, 특정 이벤트가 발생할 때마다 코드를 실행하고 싶을 때 사용합니다.
* **핵심 개념**: `when` 문과 함께 사용하여 각 라이프사이클 이벤트에 맞는 동작을 정의할 수 있습니다.
@Composable
fun AnalyticsLogger(user: User) {
// ON_RESUME 이벤트가 발생할 때마다 로그를 전송합니다.
LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
Analytics.logScreenView("Profile", user.id)
}
}
4. LifecycleStartEffect & LifecycleResumeEffect
이들은 각각 `ON_START` / `ON_STOP` 과 `ON_RESUME` / `ON_PAUSE` **쌍으로 동작하는 로직**을 처리하는 데 특화된 `DisposableEffect`입니다.
* **핵심 개념**:
* `LifecycleStartEffect`: `ON_START` 시점에 코드를 실행하고, `ON_STOP` 시점에 `onDispose` 블록을 실행합니다.
* `LifecycleResumeEffect`: `ON_RESUME` 시점에 코드를 실행하고, `ON_PAUSE` 시점에 `onDispose` 블록을 실행합니다.
* **주요 사용 사례**: `ON_RESUME`일 때 위치 정보 업데이트를 시작하고, `ON_PAUSE`일 때 중단하는 경우처럼 쌍으로 묶이는 작업에 유용합니다.
@Composable
fun LocationTrackingScreen() {
// 화면이 사용자에게 보여질 때(ON_RESUME) 위치 추적을 시작하고,
// 화면이 가려질 때(ON_PAUSE) 추적을 중지합니다.
LifecycleResumeEffect(Unit) {
val locationProvider = LocationProvider()
locationProvider.start()
onDispose {
locationProvider.stop()
}
}
}

대부분의 일회성 비동기 작업은 `LaunchedEffect`로 충분합니다.
리스너 등록/해제와 같은 명시적인 정리가 필요하면 `DisposableEffect`를, Android 라이프사이클과 더 밀접한 연동이 필요하면 `Lifecycle...Effect` 시리즈를 사용하면 됩니다.
'안드로이드' 카테고리의 다른 글
| 안드로이드 클린 아키텍처, 쉽게 이해하기. (0) | 2025.12.14 |
|---|---|
| Hilt에서 @Provides와 @Binds: 언제, 어떻게 사용해야 할까? (1) | 2025.08.10 |
| Android 프로젝트에 ktlint + Spotless 적용하기 (2) | 2025.07.27 |
| 맥북(Mac) 안드로이드 usb 테더링 설정하기 (0) | 2025.06.29 |
| 안드로이드 MVI 패턴의 핵심, Reducer 완벽 해부: 역할, 기능, 사용법 (0) | 2025.04.20 |