[TIL] ๐ŸŒผ24/05/14๐ŸŒผ#DataStore #Preferences DataStore

0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
99/104
post-thumbnail
post-custom-banner

[TIL] ๐ŸŒผ24/05/14๐ŸŒผ#DataStore #Preferences DataStore

DataStore

๐Ÿ“Œ์ฐธ๊ณ ์ž๋ฃŒ

SharedPreferences์˜ ๋ฌธ์ œ์ 

  • ๋น„๋™๊ธฐ(Asynchronous) API ์ œํ•œ์ ์œผ๋กœ ์ง€์›
    • read:
      • ๋™๊ธฐ read๋งŒ ์ง€์›
      • ๊ฐ’์— ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ OnSharedPreferenceChangeListener๋กœ ์ฝœ๋ฐฑ๋งŒ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ
    • write:
      • Editor์˜ commit()์ด ์•„๋‹Œ apply()๋ฅผ ํ†ตํ•œ ๋น„๋™๊ธฐ write ์ง€์›
      • ํ•˜์ง€๋งŒ, apply()๋„ ์ฆ‰์‹œ ๋น„๋™๊ธฐ ํ˜ธ์ถœ X
        -> pending ๋˜์—ˆ๋‹ค๊ฐ€ ์„œ๋น„์Šค/์•กํ‹ฐ๋น„ํ‹ฐ Start/Stop ์‹œ์ ์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๋™์ž‘
        -> ์ด๋•Œ ์‹คํ–‰๋˜๋Š” fsync() native ํ•จ์ˆ˜๋Š” ๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ ๋ธ”๋กํ•จ
        -> ANR ๊ฐ€๋Šฅ์„ฑ ์กด์žฌ
  • Runtime Exception์— ์ทจ์•ฝ
  • UI ์“ฐ๋ ˆ๋“œ(๋ฉ”์ธ ์“ฐ๋ ˆ๋“œ)์—์„œ ์•ˆ์ „ํ•˜์ง€ X
    • Editor์˜ commit() ํ•จ์ˆ˜

DataStore

  • DataStore?
    • new and improved data storage solution
    • Built on Kotlin coroutines and Flow
    • aimed at replacing SharedPreferences
  • DataStore์˜ ์ข…๋ฅ˜

    • Preferences DataStore
      • key-value ์Œ ์ €์žฅ์— ์‚ฌ์šฉ
    • Proto DataStore
      • custum data type ์ธ์Šคํ„ด์Šค ์ €์žฅ์— ์‚ฌ์šฉ
      • protocol buffers๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ schema๋ฅผ ์ •์˜ํ•ด์•ผ ํ•จ
      • type safety ๋ณด์žฅ๋จ
  • DataStore๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ง€์ผœ์•ผํ•  ๊ฒƒ

    • ํ•˜๋‚˜์˜ ํŒŒ์ผ์— DataStore ์ธ์Šคํ„ด์Šค ํ•˜๋‚˜ ์ด์ƒ ์ƒ์„ฑ X
      -> ๋ฐ์ดํ„ฐ read/update์‹œ IllegalStateException throw ๋จ
    • DataStore์— ์‚ฌ์šฉ๋˜๋Š” generic type ๋ฐ˜๋“œ์‹œ immutable ํ•ด์•ผ
    • ํ•˜๋‚˜์˜ ํŒŒ์ผ์— SinglePrecessDataStore๊ณผ MultiProcessDataStore ํ˜ผ์šฉ X

Preferences DataStore

  • Preferences DataStore๋Š” DataStore ํด๋ž˜์Šค์™€ Preferences ํด๋ž˜์Šค ์‚ฌ์šฉ
  • Preferences ํด๋ž˜์Šค?
    • Preferences/MutablePreferences๋Š” generic Map/MutableMap๊ณผ ์œ ์‚ฌ
    • intended for use with DataStore

Preference DataStore ์ƒ์„ฑํ•˜๊ธฐ

  • ํ•„์š”ํ•œ dependency
    dependencies {
    	// Preferences DataStore (SharedPreferences like APIs)
        implementation "androidx.datastore:datastore-preferences:1.1.1"
    }
  • preferencesDataStore์˜ property delegate ์‚ฌ์šฉ
    -> DataStore<Preferences> ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
  • Kotlin ํŒŒ์ผ ์ตœ์ƒ์œ„์— ์ •์˜
    -> access this property throughout the rest of your application
    -> singleton์œผ๋กœ ์‚ฌ์šฉ
// At the top level of your kotlin file:
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")

Preference DataStore์—์„œ ์ฝ์–ด์˜ค๊ธฐ

  • Preference DataStore๋Š” ๋ฏธ๋ฆฌ ์ •์˜๋œ schema ์‚ฌ์šฉํ•˜์ง€ X
    -> ์ €์žฅ๋  ๊ฐ’๊ณผ ๋Œ€์‘๋˜๋Š” ํƒ€์ž…์˜ key type function ์‚ฌ์šฉํ•ด์•ผ
  • DataStore.data ํ”„๋กœํผํ‹ฐ ์‚ฌ์šฉ
    -> ์ €์žฅ๋œ ๊ฐ’ Flow๋กœ ์ฝ์–ด์™€์ง
// key for an int value
val EXAMPLE_COUNTER = intPreferencesKey("example_counter")
val exampleCounterFlow: Flow<Int> = context.dataStore.data
  .map { preferences ->
    preferences[EXAMPLE_COUNTER] ?: 0 // No type safety
}

Preference DataStore์— ์“ฐ๊ธฐ

  • edit ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’ update ๊ฐ€๋Šฅ
suspend fun DataStore<Preferences>.edit(
    transform: suspend (MutablePreferences) -> Unit
): Preferences
  • transform ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ’ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ ๋ธ”๋Ÿญ ๋ฐ›์Œ
    -> transform ์ฝ”๋“œ ๋ธ”๋Ÿญ์€ ํ•œ ๊ฐœ์˜ transition์œผ๋กœ ์ทจ๊ธ‰๋จ
    (= atomic operation)

    -> ๊ฐ’์ด disk์— ์ €์žฅ๋œ ํ›„์—์•ผ coroutine ์™„๋ฃŒ๋จ
suspend fun incrementCounter() {
  context.dataStore.edit { settings ->
    val currentCounterValue = settings[EXAMPLE_COUNTER] ?: 0
    settings[EXAMPLE_COUNTER] = currentCounterValue + 1
  }
}
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€