Android/DataStore

[Android][Compose] DataStore 사용해보기

O_Gyong 2024. 4. 1.

DataStore

DataStore는 Jetpack 라이브러리로 Key-Value 또는 형식화된 객체를 프로토콜 버퍼와 함께 저장이 가능한 저장소다. 코틀린의 코루틴과 Flow를 사용하여 데이터를 비동기적이고 일관되며 트랜잭션 방식으로 저장한다.

 

기존에 SharedPreferences를 사용하고 있다면  DataStore로 마이그레이션 할 것을 구글에서 권장하고 있다.

SharedPreferences vs DataStore

원본 링크

 

 

위 이미지를 보면 PreferencesDataStore와 ProtoDataStore가 있다.  DataStore는 두 가지 구현을 제공한다.

Preferences DataStore
Key를 사용하여 데이터를 저장하고 접근한다. 미리 정의된 스키마가 필요하지 않으며 유형의 안정성도 제공하지 않는다.

◾ Proto DataStore
데이터 맞춤 데이터 유형의 인스턴스로 저장한다. 프로토콜 버퍼를 사용하여 스키마를 정의해야 하지만 유형의 안정성을 보장한다.

 

참고로 크거나 복잡한 데이터를 다루거나 참조 무결성을 지원해야 하는 경우에는 DataStore 대신 Room을 사용할 것을 권장한다.

참고 자료


DataStore 사용해보기

Compose에 앱 아키텍처를 적용하고  Preferences DataStore를 사용해봤다.

앱 아키텍처에 대해서는 codelab을 참고했다.

 

DataStore 라이브러리 등록

/**
 * build.gradle.kts
 */
val hiltVersion = 2.46

dependencies {
	...

    // Preferences DataStore
    implementation("androidx.datastore:datastore-preferences:1.0.0")
    implementation("androidx.datastore:datastore-preferences-core:1.0.0")
}

Preferences DataStore 만들기

@HiltAndroidApp
class MainApplication: Application() {
    @Module
    @InstallIn(SingletonComponent::class)
    object DataModule {
        @Singleton
        @Provides
        fun provideDataStoreRepository(@ApplicationContext context: Context)= SettingRepository(context)
        val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "pref_data")
    }
}

preferences DataStore를 사용하려면 Datastore<Prefenences>의 인스턴스가 필요하다. preferencesDataStore로 DataStore에 대한 속성 위임을 만들고 인스턴스를 생성한다.

name 속성을 통해 "datastore/"의 하위 폴더 이름을 지정할 수 있다.

DataStore 쓰기 / 읽기

class SettingRepository @Inject constructor(private val context: Context) {

    // Key 설정
    private val nameKey = stringPreferencesKey("name")

    // 쓰기
    suspend fun setName(name: String): String {
        context.dataStore.edit {
            it[nameKey] = name
        }
        return DataStoreResult.SET_NAME
    }

    // 읽기
    suspend fun getName(): Flow<String> {
        return context.dataStore.data.catch { e ->
            if (e is IOException) {
                emit(emptyPreferences())
            } else {
                throw e
            }
        }.map {
            it[nameKey] ?: "NameNull"
        }
    }
    
    ...
}
  • Key 설정
    Preferences DataStore는 정의된 스키마를 사용하지 않고, Key를 사용해서 데이터에 접근할 수 있다. 인스턴스에 저장해야 하는 각 값의 Key를 정의하려면 PreferencesKey() 함수를 사용해야 한다. 예시의 경우 String 값의 Key를 정의하기 위해서 stringPreferencesKey()를 사용했다.
  • 쓰기
    트랜잭션 방식으로 데이터를 업데이트하는 Preferences DataStore는 edit() 함수를 제공한다. edit()은 필요에 따라 값을 업데이트할 수 있는 코드 블록을 허용하여 이곳에서 값을 업데이트하면 된다.
  • 읽기
    DataStore.data 속성의 Flow를 사용하고, Key 값을 통해 필요한 데이터에 접근할 수 있다.

 

 

전체 코드

 

Android_Study/DataStore at master · OhGyong/Android_Study

안드로이드 개발 공부. Contribute to OhGyong/Android_Study development by creating an account on GitHub.

github.com

 

댓글