Protocol Buffer
λ₯Ό μ¬μ©νμ¬ Key-Value
λ°μ΄ν°λ Typed Objects
λ₯Ό μ μ₯ν μ μλ€.
DataStore
λ Coroutine + Flow
λ₯Ό μ¬μ©νμ¬ λΉλκΈ°μ μ΄κ³ μΌκ΄μ μΈ νΈλμμ
λ°©μμΌλ‘ λ°μ΄ν°λ₯Ό μ μ₯νλ€.
DataStore
λ Preferences DataStore
κ³Ό Proto DataStore
λ κ°μ§λ‘ λΆλ₯λλ€.
SharedPreferencesλ₯Ό λ체νλ μλ‘μ΄ λ°μ΄ν° μ μ₯μλ¨μ΄λ€.
DataStore
κ³Ό SharedPreference
λ₯Ό λΉκ΅νλ©΄ μμ κ°λ€.
μ λ΄μ©μ μμ½νμλ©΄,
Flow
λ₯Ό μ¬μ©νμ¬ I/Oμ λν λΉλκΈ° μ²λ¦¬κ° κ°λ₯.Dispatcher.IO
νμμμ λμνμ¬ MainThread
μμ νΈμΆλμ΄λ μμ ν¨.RuntimeException
μΌλ‘λΆν° μμ ν¨μ΄μ λ μ΄μ SharedPreference
μ μ¬μ©μ κ³ μ§ ν νμκ° μμ κ² κ°λ€.
μ±λͺ¨λμ build.gradle
μ λ€μ λ΄μ© μΆκ°
dependencies {
implementation("androidx.datastore:datastore-preferences:1.0.0")
implementation("androidx.datastore:datastore-preferences-core:1.0.0")
}
class DataStoreModule(private val context: Context) {
private val Context.dataStore by preferencesDataStore(name = "dataStore")
private val myStringKey = stringPreferencesKey("keyName")
private val myIntKey = intPreferencesKey("keyName")
}
DataStore
μμ μ¬μ©νλ ν€ κ°μ μ¬μ©ν νμ
PreferencesKey("keyName")
κ³Ό κ°μ ννλ‘ μ μΈ ν μ μλ€. μμ μμλ κ°κ° string
int
νμ
μ λ°μ΄ν°λ₯Ό μ μ₯νκΈ° μν μμμ΄λ€.
μ½λ£¨ν΄μ Flow
λ₯Ό μ¬μ©νμ¬ DataStore
μμ λ°μ΄ν°λ₯Ό μ½μ΄μ¬ λ ν΄λΉ λ°μ΄ν°λ₯Ό Flow
κ°μ²΄λ‘ μ λ¬νλ€.
// μμμ λ§λ `myStringKey` Key κ°μ λμνλ Value λ°ν
val textData: Flow<String> =
context.dataStore.data
.catch { exception ->
if (exception is IOException) {
emit(emptyPreferences())
} else {
throw exception
}
}
.map { preferences ->
preferences[myStringKey] ?: "" // μμμ λ§λ Key
}
map()
μ νμ©νμ¬ myStringKey
μ λμνλ Valueλ₯Ό Flow ννλ‘ κ°μ Έμ€κ² λλ€.
catch()
λ₯Ό μ¬μ©νμ¬ λ°μ΄ν° μ½λ κ³Όμ μμ λ¬Έμ κ° μκ²Όμ λ μμΈμ²λ¦¬λ₯Ό ν΄μ€ μ μλ€.
DataStore
μμ μ½μ λ°μ΄ν°λ₯Ό TextView
μ μ μ©ν΄λ³΄λλ‘νλ€. (λ€μ μμ
μ CoroutineScope
λ΄μμ μνλμ΄μΌνλ€.)
CoroutineScope(Dispatchers.Main).launch {
MyApplication.getInstance().getDataStore().textData.collect {
textView.text = it
}
}
λ°μ΄ν°λ₯Ό μ°κΈ° μν΄μ edit()
λ₯Ό μ¬μ©νλ€. ν΄λΉ μμ
μ λΉλκΈ°μ μΌλ‘ λμνλ―λ‘ suspend
ν€μλλ₯Ό ν΅ν΄ μ½λ£¨ν΄ μμμμ λμν μ μλλ‘ νλ€.
// String κ°μ `stringKey` μ Value λ‘ μ μ₯
suspend fun setTextData(text: String) {
context.dataStore.edit { preferences ->
preferences[stringKey] = text // μκΉ λ§λ Key μ΄μ©
}
}
μμ κ°μ΄ λ°μ΄ν°λ₯Ό μ°κΈ° μν suspend
ν¨μλ₯Ό λ§λ€μλ€λ©΄, λ€μκ³Ό κ°μ΄ νΈμΆνμ¬ μ¬μ© ν μ μλ€.
CoroutineScope(Dispatchers.Main).launch {
MyApplication.getInstance().getDataStore().setTextData("H43RO")
}
DataStore
λ₯Ό μ¬μ©νλ©΄μ λΉλκΈ° μ²λ¦¬κ° μλ λκΈ° μ²λ¦¬λ₯Ό νκ³ μΆλ€λ©΄, λ€μμ κ°μ΄ μ¬μ© ν μ μλ€.runBlocking { val text = MyApplication.getInstance().getDataStore().textData.first() }
λ€λ§,
runBlocking
μμμ λ¬΄κ±°μ΄ μμ μ νΌν΄μΌνλ€. λΈλ‘νΉ λλ μκ°μ΄ κΈΈμ΄μ§μ λ°λΌ νλ μ λλμΌλ‘ μΈν νλ©΄ λ²λ² μ(16ms), ANR(5s)λ‘ μ΄μ΄μ§ μ μλ€.
μμΌλ‘ SharedPreference
λμ DataStore
λ₯Ό μ¬μ©νμ
https://android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html
https://android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html
λ°μ΄ν°μ€ν μ΄ κ°μ¦μ!! π