왜 Datastore 에 대해 알아보는 걸까?
우리는 안드로이드 개발을 하다보면, 간단한 데이터에 대해 로컬에 저장하여 사용한다.
가볍게 SharedPreferences 를 설명하자면 Key-Value 형태로 값을 저장하여 읽고 쓰는 간단한 방법이다.
데이터는 xml 파일로 로컬 저장소에 저장된다.
우리는 왜? Datastore 를 알아볼까 Datastore 는 Kotlin 코루틴 및 Flow 를 사용하여 비동기적이고 일관된 트랜잭션 방식으로 데이터를 저장한다. 그리고 Andorid Developer 사이트에서 Datastore 사용을 권장한다.
또한 SharedPreferences 를 사용하는데에 여러 문제점이 존재한다. 그래서 권장하는 것 같고, 이제는 SharedPreferences 에서 Datastore 로 이전하는 것이 좋다고 한다.
SharedPreferences 의 문제점
1. 비동기 API 를 제한적으로 지원한다는 점
기존에 SP(SharedPreferences) 에서는 읽기(Read)에 대해 기존에 값을 읽어오는 것은 동기(sync) API 만을 제공하고, 값에 변화가 있을 때마다 비동기적으로 값을 가져오는 방법으로는 오직 OnSharedPreferenceChangeListener 를 통해서만 콜백을 받을 수 있게 지원하고 있다.
또한, 쓰기(Write) 에 대해서는 Editor 를 통해 put 하고 commit() 이 아닌 apply() 라는 함수를 통해 비동기로 write 할 수 있게 제공하고 있다. 이 apply() 도 사실 즉시 비동기 호출을 하는게 아니라 내부 코드를 보면 pending 시켜두었다가 서비스나 액티비티가 onStart, onStop 되는 시점에 백그라운드에서 동작하게 되는데, 이때 fsync() 라는 native 함수가 사실상 Main Thread 를 Block 하기 때문에 자칫 잘못하면 ANR 로 이어질 수 있다고 한다.
2. Runtime Exception 에 취약하다.
SP 는 기본적으로 Exception 에 대한 에러 핸들링을 제공하고 있지 않다. 따라서 발생하는 Exception 을 다루기에 어려움을 겪는다.
심지어 apply() 를 통해 pending 된 작업을 처리하다가 에러가 발생할 경우에는 해당 예외를 잡을 방법이 없이 Crach 를 맞이할 수 밖에 없다.
3. UI Thread 에 안전하지 않다
SP commit() 함수에서 별도의 Thread 아닌 호출된 Thread 에서 바로 File Write 를 하고 있다.
이는 파일에 쓰는 데이터가 많지 않으면 언뜻 보기에는 문제가 없어보이지만, 저사양 기기에서나 데이터 양이 많아진다면 Main Thread 를 오랫동안 Block 하면서 유저에게 버벅이는 경험을 주거나 ANR 까지도 이어질 수 있다.
이제는 Datastore 에 대해서 알아볼까?
Jetpack Datastore 는 프로토콜 버퍼를 사용하여 Key-Value 쌍 또는 Typed Object(유형이 지정된 객체)를 저장할 수 있는 데이터 저장소이다.
💡프로토콜 버퍼? 구글의 데이터를 직렬화하기 위한 메커니즘
- Datastore 는 Kotlin 코루틴 및 Flow 를 사용하여 비동기적으로 일관된 트랜잭션 방식으로 데이터를 저장한다.
- 소규모 단순 데이터에 적합한 솔루션으로, 복잡한 데이터나 참조 무결성 등을 필요로 할 때는 Room 사용이 적합하다.
- Key-Value 방식의 Preferences Datastore 와 Protocol buffer 를 사용한 타입이 지정돈 객체를 저장할 수 있는 방식인 Proto Datastore 솔루션 제공
Datastore 는 코루틴 Flow 를 통해서만 제공되기 때문에 기본적으로는 비동기 API 만을 제공한다.
하지만, first() 등을 활용한다면 동기처리로 활용할 수 있다.
또한 CorruptionHandler 이나 Flow 의 확장함수 중 catch() 등을 통해서 에러 핸들링을 잘 지원해주고 있고,
모든 무거운 작업은 Dispatchers.IO 에서 작업되기 때문에 UI Thread 에서 얼마든지 사용하더라도 안전하다 할수 있다.
SharedPreferences VS Perference Datastore VS Proto Datastore 비교
SharedPreferences | Preference Datastore | Proto Datastore | |
데이터 추출 | 선언적으로 하나씩 추출 | 코루틴 Flow 로 데이터 스트림으로 받는다. | 코루틴 Flow 데이터 스트림으로 받는다. |
동시성 프로그래밍 방식 | 직접 설계 해야함 | 코루틴 | 코루틴 |
UI 스레드 호출 안정성 | ANR 발생 가능 | Dispathcers.IO 에서 호출 되도록 강제하여 안전 | Dispathcers.IO 에서 호출 되도록 강제하여 안전 |
강한 일관성 | 보장하지 않음 | 보장 | 보장 |
타입 보장 | 보장하지 않음 | 보장 | 보장 |
'Mobile App' 카테고리의 다른 글
[안드로이드] - 클린아키텍처 - 1 (0) | 2023.01.29 |
---|---|
[안드로이드] - 클린아키텍처 - 0 (0) | 2023.01.27 |
[안드로이드] - ConstraintLayout 을 왜쓸까? (0) | 2023.01.26 |
[안드로이드] - Flow (coroutine) - 0 (0) | 2023.01.18 |
[안드로이드] - coroutine (코루틴) - 0 (1) | 2023.01.18 |