# 2021/01/05

silmxmail·2022년 1월 7일
1

1일1문서

목록 보기
12/17

https://medium.com/@joongwon/android-datastore로-이전하기-273329bb2569

DataStore를 소개합니다~

데이터스토어의 장점은 다음 그림 한장으로 표현할수 있습니다!

여러가지 장점이 있지만 DataStore의 가장 큰 장점은 Main UI 쓰레드가 아닌 별도의 쓰레드에서 실행을 시킬 수 있다는 점입니다.

DataStore는 Key, Value 형태로 저장하는 Preferences DataStore와 프로토콜 버퍼 형태로 저장하는 Proto DataStore 두 가지 구현을 제공합니다.

DataStore는 데이터를 읽어들이려면 Flow를 통해야 한다고 합니다. 즉, Flow를 통한다는 이야기는 코루틴에서 실행이 되어야 한다는 것을 의미하고 이는 자연스럽게 DataStore를 이용하려면 별도의 쓰레드에서 실행된다는 것을 알 수 있습니다.

Read


suspend inline fun <T : Any> DataStore<Preferences>.readValue(key: Preferences.Key<T>, defaultValue: T): T {
    return data.catch { recoverOrThrow(it) }.map { it[key] }.firstOrNull() ?: defaultValue
}

suspend inline fun <T : Any> DataStore<Preferences>.readValue(key: Preferences.Key<T>): T? {
    return data.catch { recoverOrThrow(it) }.map { it[key] }.firstOrNull()
}

suspend fun FlowCollector<Preferences>.recoverOrThrow(throwable: Throwable) {
    if (throwable is IOException) {
        emit(emptyPreferences())
    } else {
        throw throwable
    }
}

Write


suspend inline fun <T : Any> DataStore<Preferences>.storeValue(key: Preferences.Key<T>, value: T?) {
    edit { preferences ->
        if (value == null) {
            preferences.remove(key)
        } else {
            preferences[key] = value
        }
    }
}

Example


class ExampleDataStore(context: Context) {
    private val dataStore: DataStore<Preferences> = context.dataStore

    suspend fun setExampleData(exampleData: String?) {
        dataStore.storeValue(EXAMPLE_DATA, exampleData)
    }

    suspend fun getExampleData(): String? {
        return dataStore.readValue(EXAMPLE_DATA)
    }

    companion object {
        private const val PREF_NAME = "example_pref"

        private val EXAMPLE_DATA = stringPreferencesKey("exampleData")

        private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(
            name = PREF_NAME,
            produceMigrations = { context -> listOf(SharedPreferencesMigration(context, PREF_NAME)) }
        )
    }
}

도입을 고려한다면?

사실 SharedPreferences에서 read, write 비용이 보통은 크지 않기 때문에(데이터가 작고 주로 캐싱 해서 사용하죠) DataStore를 도입했을 때 얻을 수 있는 이득이 크냐?라는 관점에서 보면 효용이 크진 않을 것 같습니다. 그럼 반대로 굳이 도입하지 않을 이유가 있나?라고 반문해 보면 이것도 어려운 것 같네요.

DataStore는 적용하면서 얻는 가장 큰 이점은 SharedPreferences를 UI 스레드에서 무심코 호출하면서 생기는 찝찝함을 덜어낼 수 있다가 아닐까 싶네요.

정리해 보면 프로젝트가 도입하기에 유리한 환경이라면 별 무리 없이 적용할 수 있어서 좋을 것 같지만 굳이 DataStore를 도입하기 위해 많은 부가적인 작업들을 하면서까지 도입하기에는 충분한 메리트가 있는지 잘 모르겠습니다.

RxJava 버전도 지원을 하니 Java 환경에서도 사용이 가능할 것 같지만.. 개인적인 느낌으로는 Kotlin & Coroutine 환경에서 사용하기가 딱 좋다고 느껴지네요.

profile
러닝커브를 따라서 등반중입니다.

0개의 댓글