앱 MVP Android DataStore: 설정·구조화 상태·대용량 데이터를 나누는 5가지 기준
Android 앱 MVP에서 “설정은 기기에 저장하면 된다”는 말은 시작으로는 충분하지만, 구현 결정을 끝내기에는 너무 넓습니다. 다크 모드·정렬 방식 같은 작은 선택값, 여러 화면이 함께 보는 구조화된 상태, 검색·주문처럼 관계가 있는 데이터, 사용자가 남기는 파일은 수명과 검수 방법이 서로 다릅니다.
Android Developers는 Jetpack DataStore를 키-값 또는 타입이 있는 객체를 저장하는 솔루션으로 설명합니다(C001). 동시에 큰·복잡한 데이터 집합, 부분 갱신, 참조 무결성이 필요한 경우에는 DataStore 대신 Room을 검토하라고 안내합니다(C002). 그러므로 “로컬 저장을 넣었다”가 아니라 무엇을 어느 저장 경계에 둘지를 먼저 결정해야 합니다.
먼저 답: 설정값, 화면 상태, 업무 데이터, 파일은 같은 저장 문제가 아닙니다
초기 MVP는 보통 하나의 설정 화면에서 시작하지만, 시간이 지나면 로그인한 사용자별 선택값, 서버에서 내려오는 기능 플래그, 오프라인에서 수정되는 업무 데이터, 업로드 전 파일이 섞이기 쉽습니다. DataStore의 읽기와 갱신 성공은 서버의 업무 완료, 사용자 동의, 파일 업로드 완료를 증명하지 않습니다. 각각의 완료 신호와 재시도 기준을 분리해 두어야 합니다.
이 글은 특정 라이브러리를 “정답”으로 추천하지 않습니다. Android의 공식 범위를 기준으로, 팀이 저장 대상의 크기·관계·변경 방식·프로세스·UI 노출을 질문으로 바꾸는 방법을 다룹니다.
기준 1: 작은 선택값과 구조화된 상태를 먼저 구분합니다
키를 중심으로 작게 저장하고 미리 정한 스키마가 필요 없다면 Preferences DataStore를 검토할 수 있습니다. Android 문서는 이 구현이 사전 스키마를 요구하지 않고 타입 안전성을 제공하지 않는다고 설명합니다(C003). 반대로 앱이 정의한 객체를 지속하려면 스키마와 직렬화 방식이 필요하며, Proto DataStore는 proto 파일에 미리 정의한 스키마를 사용합니다(C004).
여기서 중요한 것은 이름이 아니라 변경 비용입니다. 예를 들어 “알림 허용 안내를 본 적이 있는가”처럼 한 값이면 키와 기본값을 명시하면 됩니다. 반면 여러 필드가 함께 움직이고 버전별 의미를 관리해야 한다면 객체의 기본값, 스키마 변경, 읽기 실패 시 동작을 요구사항에 남기세요. 값이 화면에 보였다는 사실만으로 사용자가 실제 설정을 이해하거나 서버 정책이 적용됐다고 해석하면 안 됩니다.
기준 2: 관계·부분 갱신이 필요한지부터 Room과 나눕니다
DataStore는 작은 데이터 집합에 알맞고 부분 갱신이나 참조 무결성을 지원하지 않습니다(C002). 따라서 목록의 행을 일부만 수정하거나, 여러 엔터티의 관계를 보존하거나, 검색·정렬·조회 조건이 핵심인 업무 데이터라면 “설정 저장소를 확장”하기보다 Room 같은 데이터베이스 선택을 별도로 검토해야 합니다.
판단 질문은 단순합니다. 한 값이 바뀔 때 객체 전체를 함께 다뤄도 되는가, 다른 항목과의 관계를 검증해야 하는가, 특정 항목만 자주 고쳐야 하는가입니다. 세 질문 중 하나라도 제품 동작에 중요하다면 저장 모델과 마이그레이션·테스트를 분리하세요. Room의 기존 사용자 경로가 궁금하다면 Android Room 데이터베이스 마이그레이션 기준도 함께 보세요.
기준 3: 같은 파일에는 같은 프로세스에서 DataStore 하나만 둡니다
Android 문서는 같은 프로세스에서 같은 파일에 대해 DataStore 인스턴스를 둘 이상 만들지 말라고 안내합니다. 여러 인스턴스가 활성화되면 읽기나 갱신에서 예외가 발생할 수 있습니다(C005). 그래서 MVP에서는 화면·Repository·Service가 각자 저장소를 만들지 않도록 생성 위치와 파일명을 한 곳에서 관리하는 편이 안전합니다.
또한 DataStore에 쓰는 제네릭 타입은 불변이어야 하며, 가변 타입을 바꾸면 DataStore가 제공하는 일관성이 무너질 수 있다고 Android 문서는 경고합니다(C006). “저장 호출이 끝났다”가 팀의 동시성·상태 복원이 끝났다는 의미가 아닌 이유입니다. 값의 소유자, 갱신 함수, 실패 시 화면 상태를 문서로 분리하세요.
기준 4: 앱과 별도 프로세스가 같은 파일을 쓰는지 확인합니다
단일 프로세스와 다중 프로세스 DataStore를 같은 파일에 섞어 쓰면 안 됩니다(C007). Android는 여러 프로세스에서 같은 데이터에 접근해야 할 때 MultiProcessDataStore를 사용하도록 안내하며, 이 경우 읽기는 디스크에 저장된 데이터만 반환하고 read-after-write 일관성, 직렬화된 쓰기 같은 성질을 제공합니다(C008).
별도 프로세스 Service가 있는지, 위젯·다른 구성요소가 어떤 파일을 읽는지, 앱만의 내부 파일인지부터 확인하세요. 파일 자체의 수명도 별도입니다. Android의 앱 전용 저장소 문서는 앱 제거 시 그 저장소의 파일이 삭제되므로, 사용자가 앱 밖에서도 계속 보존되길 기대하는 파일에는 적합하지 않다고 설명합니다(C009). 저장 성공과 사용자 기대 수명은 같은 질문이 아닙니다.
기준 5: UI는 저장소를 직접 만지지 않고, 갱신은 한 단위로 검증합니다
DataStore의 updateData는 현재 객체를 받아 원자적인 읽기-수정-쓰기 트랜잭션으로 갱신합니다(C010). 이 사실은 어떤 사업 규칙도 자동으로 원자화하지 않습니다. 예를 들어 “서버 동의 저장 → 기기 설정 반영 → 다음 화면 노출”은 네트워크·저장소·UI 각각의 결과를 확인해야 합니다.
Compose 앱에서는 DataStore 작업을 data layer나 Repository에 두고 ViewModel을 거쳐 UI에 노출하며, composable 함수에서 직접 읽고 쓰지 말라고 Android 문서는 안내합니다(C011). 이를 MVP QA에 적용하면, 기본값 화면, 저장 중 상태, 실패·재시도, 앱 재실행 후 읽기, 서버 값과 충돌할 때의 우선순위를 각각 테스트 케이스로 만들 수 있습니다.
확인 층 | 결정 질문 | 완료로 보지 말아야 할 것 |
|---|---|---|
대상 | 작은 선택값·구조화 상태·관계형 데이터·파일 중 무엇인가 | 로컬 저장 API를 추가한 사실 |
모델 | 키·스키마·기본값·불변성은 무엇인가 | 화면에 값 하나가 보인 사실 |
동시성 | 파일·프로세스별 인스턴스는 하나인가 | 한 화면에서만 저장 성공한 사실 |
업무 | 서버 처리와 기기 반영을 어떻게 나누는가 | DataStore 갱신 콜백 |
QA | 재시작·실패·충돌·제거 뒤 기대 상태는 무엇인가 | 정상 경로 한 번 통과 |
결국 DataStore 선택의 핵심은 저장 기술의 이름이 아니라, 어떤 값이 작고 독립적인지, 무엇이 관계와 부분 수정이 필요한지, 사용자가 무엇을 계속 보존되리라 기대하는지를 구분하는 데 있습니다. 그 경계가 있어야 출시 뒤의 설정 오류를 업무 데이터 손실이나 사용자 동의 오류로 오인하지 않습니다.
공식 출처
Android Developers: DataStore (2026-09-21 직접 확인)
Android Developers: Access app-specific files (2026-09-21 직접 확인)
자주 묻는 질문
Preferences DataStore와 Proto DataStore는 어떻게 고르나요?
작은 키-값 선택을 저장하고 사전 스키마가 필요 없다면 Preferences DataStore를 검토할 수 있습니다. 타입이 있는 객체를 지속하려면 스키마와 직렬화 방식을 정해야 하며 Proto DataStore는 proto 스키마를 사용합니다.
DataStore에 업무 목록과 관계형 데이터를 넣어도 되나요?
Android 문서는 큰·복잡한 데이터 집합, 부분 갱신, 참조 무결성이 필요할 때 Room을 검토하라고 안내합니다. 목록의 일부 수정이나 관계 검증이 핵심이면 저장 모델을 따로 설계하세요.
같은 파일의 DataStore를 화면마다 만들어도 되나요?
아닙니다. Android 문서는 같은 프로세스에서 같은 파일에 DataStore 인스턴스를 둘 이상 만들지 말라고 안내합니다. 생성 위치와 파일명을 한 곳에서 관리하는 편이 좋습니다.
DataStore 갱신 성공은 서버 동의나 업무 완료를 뜻하나요?
아닙니다. updateData의 트랜잭션은 저장 객체의 갱신 범위입니다. 네트워크 요청, 서버 처리, 사용자 화면 반영은 별도 결과로 확인해야 합니다.
발행일: 2026-09-21 · 작성: 유인어스 정책자금·정부지원사업 인사이트