본문 바로가기

Android/AAC

[Android] Jetpack DataStore 실전 압축 정리

728x90

Preference 가 API level 29 부터 deprecated 가 되었다.

 

그래서 jetPack DataStore 를 사용하라고 한다.

API 29 부터 deprecated 된것이지만 필자는 이것을 최근에야 알았다.

 

따라서, DataStore 에 대해서 알아보고자 한다.

 


우선,

DataStore 는 무엇인가?

프로토콜 버퍼를 사용하여 Key-Value 쌍 또는 유형이 지정된 객체저장할 수 있는 데이터 저장소 솔루션 이다.

또한, Preference DataStore, Proto DataStore 의 2가지 존재가 존재한다.

 

  • Preference DataStore : 기존에 Preference 와 마찬가지로, Key 를 사용하여 데이터를 저장하고, 가져온다.
  • Proto DataStore : 사용자가 정의한 타입으로 데이터를 저장한다. 이 때, 프로토콜 버퍼를 사용하여 스키마를 정의해야 한다.

여기서 필자는 Proto DataStore 에 대한 사용은 하지 않으려고 한다.

기존에 사용하던 프로젝트에서도 Key-Value 타입의 Preference 를 사용하고 있었기 때문에, 사용할 데이터 타입을 직접 생성하고 사용하는 Proto DataStore 는 사용할 필요가 없으며 Preference DataStore 만 사용해도 충분하다고 생각했기 때문이다.

 

DataStore 에 대해서 공부하려고 찾아보면, DataStore 의 장점을 보여줄 수 있는 다음과 같은 표를 쉽게 찾아볼 수 있다.

 

출처 : https://android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html

 

위의 표를 확인해 보면 DataStore 는 크게 이런 특징이 존재한다.

  • Flow 를 사용하여 데이터를 읽는다. 즉, 코루틴을 사용해야 한다.
  • IO 스레드 밑에서 동작한다.
  • runtime Exception 에서 안전하다.

필자는 DataStore 를 Preference가 deprecated 되었기 때문에 사용하려고 생각하였지만, 위와 같은 다양한 장점들이 존재하는 것을 알 수 있다.


그렇다면,

어떻게 사용해야 할까?

DataStore 를 사용하기 위해서는 우선 Gradle 에 라이브러리를 추가해 주어야 한다.

 

하단의 rxJava2 는 없어도 무관하지만, support 라고 되어있길래 추가시켜보았다. DataStore 를 사용하는 것에는 필요하지 않다.

 

추가해 주었으면, DataStore 를 생성하여 사용하면 된다.

 

우선, 위의 코드는 DataStore 의 전체 소스코드이다.

전체 소스코드 부터 넣어두는 이유는, 필자가 DataStore 를 사용해보기 위해서 Android Developer 를 보고 따라해 보았는데 정상적으로 안됐던 부분이 많았기 때문이다.

 

위의 코드를 3개의 구분으로 나누어서 확인해보자.

 

DataStore 의 생성부분과 DataStore 에 값을 저장할 때 사용할 Key 값을 설정해 주는 부분이다.

 

dataStore 에 설정하는 name 값은 해당 DataStore 의 이름을 설정해주는 것이고, 여러가지 매개변수가 추가로 들어갈 수 있지만 필수로 들어가야하는 name 에 대한 값만 넣어주도록 한다.

 

Key 값을 설정하는 부분은 저장할 value 의 type 에 따라서 다르게 선언을 해주어야 한다.

stringPreferencesKey(name) 형태로 선언되어 있는데, string 부분에 저장할 Value 의 Type 을 넣어주면 된다.

즉, int 타입이라면 intPrefenencesKey(name) 형태로 선언하여 사용하면 되는 것이다.

 

 

다음으로 데이터를 저장하는 부분이다.

데이터를 저장할때는 edit() 를 사용하여 아주 간단하게 사용할 수 있다.

하지만, edit() 의 경우 비동기로 작업이 이루어져야 하는 부분이기 때문에 일반적인 함수로 사용할 수 없으며,

suspend 를 사용하여 코루틴 환경에서 해당 함수가 호출되어 값이 저장되도록 해야한다.

 

stringKey 의 자리에는 상단에 선언한 Key 값을 사용하는 것이고, text 부분에는 저장할 데이터가 들어가면 된다.

 

마지막 부분인 데이터를 가져오는 부분이다.

반환되는 자료형을 보면 알 수 있겠지만 DataStore 의 큰 특성 중 하나인 Flow 를 통해 데이터가 반환되며, map 을 사용하여 DataStore 에 가지고 있는 값을 key 값을 사용하여 가져오도록 되어있다.

또한, 값을 읽어오는 과정에서 오류가 발생하는 경우가 발생할 수 있으며 이 때는 IOException 이 발생한다.

따라서 catch 를 사용하여 해당 exception 에 대한 처리를 하여 앱이 죽거나 하는 것 없이 빈 값을 전달하도록 구현을 해준다.

 

값을 가져올 때 우리가 원하는 Data Type 이 아니라 Flow 이기 때문에, dataStoreText 라는 변수를 사용하여 값을 저장하거나 할 수는 없다.

따라서, 사용하는 부분에서 별도의 처리를 해주어야한다는 점을 인지하고 있어야 한다.


위와 같이 DataStore 에 대해 선언을 해주었으면,

생성하는 부분도 확인을 해보야 한다.

 

 

필자는 Application 에서 DataStore 를 생성하여 사용하도록 구현해보았다.

Application 단에서 생성하지 않아도 되지만, 필자와 같은 경우에는 Application 단에서 사용하는 Koin 과 같은 것들도 있기 때문에 한번에 처리하기 위해서 이곳에서 생성하도록 하였다.

 

이곳에서 자세히 봐야 할 부분은 instance 를 가져오는 부분이다.

Application 단에 선언한 DataStore 를 사용하기 위해서는 Application 의 instance 가 필요하기 때문에 getInstance 를 통해 외부에서 해당 instance 를 가져오게 되는 것이고,

getDataStore 를 통하여 외부에서 Application 단에서 생성한 dataStore에 대한 instance 를 가져올 수 있게 되는 것이다.


마지막으로, 

DataStore 를 사용하는 부분에 대해서 확인해 보자.

 

 

DataStore 에 Set 하는 부분이다.

suspend로 선언한 setDataStoreText() 를 사용하기 위하여 코루틴을 사용하여 비동기적으로 호출한다.

코루틴 혹은 Rx를 사용하여 비동기로 호출하는 것 외에는 별도로 신경써서 작업할 부분은 없다.

 

 

DataStore 에서 Get 하는 부분이다.

주석에도 작성을 해두었다시피 동기 처리를 하기위하여 async와 await() 를 사용하였고, 때문에 suspend 를 붙이게 되었다. 만약, 값을 읽어오는것에 있어서 동기 처리가 필요하지 않고 비동기로 처리해도 무관하다면 await 를 사용하지 않고 그냥 호출하면 될 것이다.

 

값을 읽어오는데 first() 를 사용하였는데, 비동기적으로 원하는 타이밍에 한번만 값을 가져오는 경우에는 first() 사용하여 가져오면 된다.

필자가 지금까지 사용했던 패턴을 생각해보았을 때, 해당 방식을 주로 사용하였기 때문에 first() 를 사용하여 예제를 구현해 보았다.

 

first() 가 아닌 collect() 를 사용하여 값을 읽어오도록 사용할 수 있는데, 이 경우 다음과 같이 구현하여 사용하면 된다.

 

 

위의 사용 방법의 경우, 필자가 설명을 위해서 임시로 만들어둔 것이기 때문에 대충 작성한 것이지만,

collect 내부의 save = it 과 마찬가지로 flow 에서 값을 읽어와서 사용하도록 할 수 있다.


위와 같이 구현을 해두었다면, 단순한 호출을 통하여 데이터를 get/set 할 수 있게 된다.

 

필자가 학습을 위해 예제를 수정하면서 호출 한 부분이다.

viewModel 에 set/get 함수를 선언해 두었고, 그것을 사용하여 버튼을 클릭하였을 때 값을 저장하거나 읽어오도록 구현한 부분이다.

 

해당 게시글에 사용한 예제는 GitHub 에 올려두었다.

https://github.com/HeeGyeong/ModuleArchitecture

 

GitHub - HeeGyeong/ModuleArchitecture

Contribute to HeeGyeong/ModuleArchitecture development by creating an account on GitHub.

github.com


Preference가 deprecated 가 되었다고 하여서 DataStore로 바꾸고자 학습을 진행하였는데,

생각보다 사용하기가 까다로운면이 있는 것 같다.

설정부터 사용까지 DataStore 가 고려해야할 부분이 더 많기도 하고, 비동기적 처리, 코루틴, Flow 등 사용하기 위해서 습득해야할 지식들이 좀 있는것으로 보인다.

 

하지만 뭐,

DataStore 를 사용하는것을 권장하는 것에는 이유가 있지 않을까 싶다.

아직 단순히 학습을 위해 예제만 만들어 보았기 때문에 이것을 사용하는 장점에 대해서는 느끼지 못하였지만,

실제로 프로젝트에 적용하고 사용해보다 보면 DataStore의 장점을 알 수 있지 않을까 생각한다.

728x90