Files
2nd/10_Wiki/Topic_Programming/Coding/Android_DataStore_Patterns.md
T
Antigravity Agent 9148c358d0 docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를
Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류.

- 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로
  자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거,
  동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거.
- 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming,
  Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business,
  Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로,
  나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는
  title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백).
  원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지.
- 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서.
- 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는
  지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지.
- Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경.
- 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
2026-07-05 00:33:48 +09:00

4.0 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
android-datastore-patterns Android DataStore — SharedPreferences 의 후계자 Coding draft B conceptual 2026-05-09 2026-05-09
android
datastore
preferences
vibe-coding
language applicable_to
Kotlin / Jetpack DataStore
Android
Preferences DataStore
Proto DataStore
EncryptedSharedPreferences

Android DataStore

SharedPreferences 는 deprecated. Preferences DataStore (Map<String, Any>) 또는 Proto DataStore (typed) 사용. Coroutines + Flow 기반. 비밀은 EncryptedSharedPreferences 또는 Keystore.

📖 핵심 개념

  • Preferences DataStore: key-value, type-unsafe. SharedPreferences 1:1 대체.
  • Proto DataStore: 타입 안전 schema. 복잡 객체.
  • 비밀: EncryptedSharedPreferences 또는 SQLCipher Room.

💻 코드 패턴

Preferences DataStore

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")

class SettingsRepo(private val ds: DataStore<Preferences>) {
    private val keyTheme = stringPreferencesKey("theme")
    private val keyOnboarded = booleanPreferencesKey("onboarded")

    val theme: Flow<String> = ds.data.map { it[keyTheme] ?: "system" }
    val onboarded: Flow<Boolean> = ds.data.map { it[keyOnboarded] ?: false }

    suspend fun setTheme(t: String) {
        ds.edit { prefs -> prefs[keyTheme] = t }
    }
    suspend fun setOnboarded(v: Boolean) {
        ds.edit { it[keyOnboarded] = v }
    }
}

Proto DataStore (타입 안전)

// app/src/main/proto/settings.proto
syntax = "proto3";
option java_package = "com.example.app";
option java_multiple_files = true;

message Settings {
  string theme = 1;
  bool onboarded = 2;
  int32 launch_count = 3;
}
object SettingsSerializer : Serializer<Settings> {
    override val defaultValue = Settings.getDefaultInstance()
    override suspend fun readFrom(input: InputStream): Settings = Settings.parseFrom(input)
    override suspend fun writeTo(t: Settings, output: OutputStream) = t.writeTo(output)
}

val Context.settings: DataStore<Settings> by dataStore(
    fileName = "settings.pb",
    serializer = SettingsSerializer
)

// 사용
val theme: Flow<String> = ctx.settings.data.map { it.theme }
ctx.settings.updateData { it.toBuilder().setTheme("dark").build() }

Encrypted (비밀)

val masterKey = MasterKey.Builder(ctx).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build()

val securePrefs = EncryptedSharedPreferences.create(
    ctx, "secure_prefs", masterKey,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
securePrefs.edit().putString("token", "...").apply()

(EncryptedDataStore 는 정식 X — 위 패턴 또는 SQLCipher.)

🤔 의사결정 기준

데이터 저장
단순 설정 (theme, locale) Preferences DataStore
복잡 객체 (다수 필드, nested) Proto DataStore
검색 / 쿼리 필요 Room
비밀 (token) EncryptedSharedPreferences / Keystore
큰 파일 File API
인메모리 임시 ViewModel 또는 SavedStateHandle

안티패턴

  • SharedPreferences 신규 사용: deprecated. DataStore.
  • DataStore 작업을 main thread: suspend / Flow 만 — 자동.
  • MutableStateFlow 로 캐시 + DataStore 둘 다 변경: 동기화 깨짐. 한 진실원.
  • 큰 데이터를 Preferences DataStore: 매 변경 전체 rewrite. Proto 또는 Room.
  • 비밀을 Preferences DataStore: 평문. Encrypted.
  • runBlocking 으로 동기 read: 메인 스레드 block. Flow + collectAsStateWithLifecycle.
  • migration 안 함 (SharedPrefs → DataStore): 옛 데이터 사라짐. SharedPreferencesMigration 사용.

🤖 LLM 활용 힌트

  • 신규 = DataStore. 비밀은 EncryptedSharedPreferences.
  • 복잡 schema 면 Proto.

🔗 관련 문서