
59. 장시간 실행되는 백그라운드 작업 관리
- WorkManager: 앱 종료/재부팅 이후에도 지속해야 하는 작업 (예: 로그 업로드, 데이터 동기화)
- Service / ForegroundService: 음악 재생, 위치 추적 등 지속 실행이 필요한 작업
- Coroutine + Dispatcher: 앱 생명주기 내에서 필요한 작업 (일시적, UI 상태 연동)
- JobScheduler: 시스템 수준 제약조건 기반 작업 (예: 충전 중 실행 등)
실전 예시: 대용량 다운로드는 ForegroundService가 적절함 (사용자 인지 필요 + 앱 종료 대비)
60. JSON 직렬화/역직렬화
- 정의:
- 직렬화: 객체 → JSON 문자열
- 역직렬화: JSON 문자열 → 객체
- 수동 변환: 직접 파싱 (비추천, 유지보수 어려움)
- 권장 라이브러리:
- kotlinx.serialization: KMP 완전 지원, 컴파일 타임 안전성
- Moshi: Kotlin 친화적, 코드젠 + KSP 기반 고성능
- Gson: 간단하지만 Kotlin 지원 약함, 리플렉션 기반 느림
실전 팁: Kotlin 우선 개발 시에는 kotlinx.serialization 선호
61. 네트워크 요청 처리
- Retrofit:
- 선언적 API 인터페이스
- JSON 변환 라이브러리와 연동 (Gson/Moshi/kotlinx.serialization)
suspend fun으로 Coroutine과 결합
- OkHttp:
- Retrofit 내부 HTTP 클라이언트
- Interceptor/Authenticator로 인증/로깅/캐싱 구현 가능
- 에러 처리 & 재시도: Coroutine
retry 또는 OkHttp Interceptor 사용
실전 예시: OAuth 사용 시 토큰 만료 → Authenticator로 자동 갱신
62. 페이징 시스템
- 필요성: 대용량 데이터 로딩 시 메모리 효율/사용자 경험 최적화
- 수동 페이징 구현 단계:
ListAdapter → DiffUtil 사용
RecyclerView.addOnScrollListener() → 마지막 항목 접근 시 다음 페이지 요청
- 데이터 추가 후
submitList() 호출
대안: Jetpack Paging3 라이브러리 사용 (추천)
63. 네트워크 이미지 로딩
- Glide: 강력한 기능, 전통적 UI 기반 앱에 적합
- Coil: Kotlin 우선, Compose 지원, 가볍고 빠름 (추천)
- Fresco: 메모리 최적화, 고급 기능 중심
실전 팁: Compose 사용 시 Coil이 가장 자연스럽고 가볍게 통합됨
64. 로컬 데이터 저장 방식
| 목적 | 도구 | 설명 |
|---|
| 설정값 저장 | SharedPreferences / DataStore | 단순 키-값, DataStore는 비동기 + Flow 지원 |
| 구조화 데이터 | Room | SQLite 추상화, Entity/Dao 기반 |
| 파일 저장 | File API | 이미지, 바이너리 등 사용자 정의 데이터 |
실전 팁: 대용량 JSON 저장 시 Room + TypeConverter 또는 파일 저장 고려
65. 오프라인 우선 기능
- 로컬 우선 읽기 → 네트워크 갱신 필요 시 동기화
- Room + WorkManager 조합: 데이터 지속성 + 조건부 백그라운드 동기화
- 충돌 해결 전략: 마지막 쓰기 우선, 수동 해결 등
예시: 뉴스 앱 - 오프라인 캐시 → 네트워크 연결 시 WorkManager 통해 서버 동기화
66. 초기 데이터 로딩 위치
| 위치 | 장점 | 단점 |
|---|
| ViewModel.init | 단일 진입점, 생명주기 안전 | 재호출 어려움, 테스트 불리 |
| LaunchedEffect | Compose와 밀접 | recomposition 주의 필요 |