원문
https://medium.com/@shalutd007/welcome-datastore-good-bye-sharedpreferences-4bf68e70efdb
https://developer.android.com/topic/libraries/architecture/datastore
원문을 읽으면서 제가 공부하려고 번/의역한 것입니다.
Jetpack DataStore
DataStore는 Key-Value쌍 또는 Protocol buffers를 이용한 Typed Object형태로 데이터를 저장할 수 있게 해주는 솔루션이다.
DataStre는 Kotlin의 Coroutine과 Flow를 사용해서 데이터를 비동기적이고, 일관적으로 저장할 수 있다. 또한 SharedPreference로 부터의 migration도 지원하고있어서 현재 작업중인 프로젝트에서 대체하기도 편하다.
DataStore의 종류
DataStore는 2가지 종류가 있다.
1. Preferences DataStore
SharedPreferences 처럼 Key를 이용해 데이터를 저장하고, 접근한다.
스키마를 정의 하거나, 타입을 보장받을 수 없다.
2. Proto DataStore
사용자가 정의한 형식의 데이터를 저장할 수 있다.
Protocol buffers를 통해서 스키마를 정의해야한다. Protocol buffers는 데이터의 타입을 보장해준다.
SharedPrefences가 데이터를 저장하는 방법인 XML 등의 형식보다 훨씬더 빠르고, 단순하다.
Prefences DataStore 사용하는 방법
1. 필요한 디펜던시를 app module에 추가한다.
1 2 3 4 | dependencies { // Preferences DataStore implementation "androidx.datastore:datastore-preferences:1.0.0-alpha01" } | cs |
2. Preferences DataStore를 생성한다.
createDataStore의 인자에는 이름을 쓴다.
1 2 3 | class PrefSettingsManager(val context: Context) { private val dataStore = context.createDataStore("datastore_name") } | cs |
3. Preferences DataStore에서 읽기
Preferences DataStore는 사전에 정의된 스키마를 사용하지 않기 때문에, preferencesKey() 메소드를 사용하여 저장할 값 각각에 대해 Key를 정의해야한다.
그리고 나서 DataStore.data 속성을 통해 Flow로 적절한 값을 가져올 수 있다.
1 2 3 4 5 | val EXAMPLE_COUNTER = preferencesKey<Int>("example_counter") // Key은 example_counter이고, Int형 값임 val exampleCounterFlow = Flow<Int> = dataStore.data .map { prefs -> prefs[EXAMPLE_COUNTER] ?: 0 } | cs |
4. Preferences DataStore에 쓰기
Preferences DataStore는 데이터를 트랜잭션 방식으로 업데이트하는 edit()이라고하는 메소드를 제공한다. edit 블록 안에있는 코드는 모두 하나의 트랜잭션으로 간주된다.
1 2 3 4 5 6 | suspend fun incrementCounter() { dataStore.edit { settings -> val currentCounterValue = settings[EXAMPLE_COUNTER] ?: 0 settings[EXAMPLE_COUNTER] = currentCounterValue + 1 } } | cs |
5. Activity에서 값 읽고 쓰기
아래 코드는 액티비티에서 DataStore에 저장된 값을 읽고, 쓰는 간단한 예제다.
액티비티에 "Black" 이랑 "White"라고 적혀있는 버튼이있고, 유저가 버튼을 누르면
Black -> android.R.color.black
White -> androidR.color.white 라는 값이 DataStore에 저장된다.
그리고 Flow로현재 DataStore에 있는 값을 읽어 배경색으로 지정한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | class PrefDataStoreActivity : AppCompatActivity() { private lateinit var prefSettingsManager: PrefSettingsManager private lateinit var outerView: View override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_datastore) title = getString(R.string.preferences_datastore) outerView = findViewById(R.id.outerView) prefSettingsManager = PrefSettingsMaanger(this) readSettings() btn_white.setOnClickListener { updateSettings(android.R.color.white) } btn_black.setOnClickListener { updateSettings(android.R.color.black) } } // 쓰기 fun updateSettings(color: Int) { GlobalScope.launch { prefSettingsManager.updateColor(color) } } // 읽기 fun readSettings() { GlobalScope.launch { prefSettingsManager.userPreferencesFlow.collect { // 배경색 지정 outerView.setBackgroundColor( ContextCompat.getColor(this@PrefdataStoreActivity, it.color) ) } } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class PrefSettingsManager(val context: Context) { private val dataStore = context.createDataStore("settings_pref") val userPreferencesFlow: Flow<UserPreferences> = dataStore.data .catch { exception -> if (exception is IOException) { emit(emptyPreferences()) } else { throw exception } }.map { preferences -> val color = preferences[BG_COLOR]?: android.R.color.white UserPreferences(color) } suspend fun updateColor(color: Int) { dataStore.edit { preferences -> preferences[BG_COLOR] = color } } } | cs |
- 글이 길어져서 Proto DataStore는 따로 다뤄보도록 하겠습니다.
'프로그래밍 > Android' 카테고리의 다른 글
[안드로이드] 서비스(Service)에 대해 알아보자 (0) | 2020.10.13 |
---|---|
[안드로이드] Proto DataStore 사용법 (2) | 2020.10.10 |
[안드로이드] FragmentStateAdapter / FragmentPagerAdapter 차이, 사용법 (0) | 2020.10.05 |
[안드로이드] Checkbox의 Style을 코드상에서 지정해 주는 방법 (set check box style programmatically) (0) | 2020.09.29 |
[안드로이드] Decorator, 귀찮은 커스텀 ItemDecoration 만들기는 그만! (0) | 2020.09.28 |