https://goni95.tistory.com/173
1️⃣SharedPreference
SharedPreference는 DB를 사용하기엔 부담스러운 간단한 설정 값 또는 문자열 같은 데이터를 키-값 쌍으로 로컬에 저장할 수 있는 데이터 저장소로 해당 데이터에 대한 파일이 애플리케이션 디렉토리 내(data/data/패키지명/shared_prefs/SharedPreference명.xml)에 존재하기 때문에 애플리케이션을 삭제하면 해당 파일도 함께 삭제됩니다.
Google에서 SharedPreference 대신 Datastore를 사용하는 것을 적극 권장하고 있기 때문에 예제 대신 사용법만 작성하겠습니다.
SharedPreference 단점
- 실제 XML 파일 I/O 작업을 하는 것이기 때문에 UI Thread에서 작업할 경우 안전하지 않다.
- Runtime Exception으로 부터 안전하지 않다.
- XML 파일이기에 외부에서 쉽게 파일을 읽을 수 있다. (Datastore도 동일)
- 비동기 API를 제공하지만 Listener를 통해서만 값을 읽을 수 있다.
- *type safety를 제공하지 않는다.
SharedPreference 유형
getPreferences(int mode) : 별도의 파일명을 지정하지 않고 자동으로 호출한 액티비티 이름의 파일 내에 저장됩니다. 즉, 하나의 파일을 다룰 것이라면 이 메서드를 통해 인스턴스를 얻어오면 됩니다.
getSharedPreferences(String name, int mode) : 파일명에 대한 정보를 지정하여 XML 파일을 생성합니다. 즉, 저장할 데이터가 많아 여러 개의 파일로 나누어 관리하고자 한다면 이 메서드를 통해 인스턴스를 얻어오면 됩니다.
위에서 볼 수 있듯이 SharedPreference의 인스턴스를 얻고자 하는 경우 mode를 매개변수로 넘겨야 하는데, Context를 통해 얻을 수 있습니다.
3가지 mode가 있지만 외부 앱에서 접근할 수 있도록 설정하는 mode인 MODE_WORD_READABLE / WRITEABLE는 보안상의 이유로 Android 4.2 (JELLYBEAN_MR1 : API 17) 부터 deprecation 되었고 앱 내에서만 접근 가능한 MODE_PRIVATE를 사용하면 됩니다.
SharedPreference로 데이터 저장
하려면 SharedPreference 인스턴스로 부터 Editor 클래스의 함수인 edit()를 통해 Editor 객체를 얻어와 put***() 메서드를 통해 매개변수로 key, value를 넘겨 키-값 쌍으로 데이터를 저장하면 됩니다.
그 후 SharedPreference의 데이터 변경을 반영하기 위해서 commit(), apply() 메서드를 호출해주면 됩니다.
commit() 메서드는 호출 시 스레드를 block 시키고 커널에서 저장이 완료되면 Boolean을 리턴하면서 block을 해제하기 때문에 결과값이 필요한 것이 아니라면 apply() 메서드를 호출하는 것이 좋습니다.
SharedPreference의 데이터 가져오기
SharedPreference의 인스턴스로 부터 get***(String key, Type value) 메서드를 통해 매개변수로 key, defaultValue를 넘겨 데이터를 가져올 수 있습니다.
SharedPreference의 데이터 삭제(특정 데이터 / 모든 데이터)
특정 데이터를 삭제하고 싶다면 Editor 객체를 통해 remove(String key) 메서드를 사용해 데이터를 삭제하고, 모든 데이터를 삭제하고 싶다면 Editor 객체를 통해 clear() 메서드를 사용하면 됩니다.
그 후 SharedPreference의 데이터 변경을 반영하기 위해서 commit(), apply() 메서드를 호출해주면 됩니다.
Datastore를 한번 공부해볼텐데 우선 안드로이드에서 로컬로 데이터를 저장할 때 Datastore, SharePreferences, Room 등을 사용합니다. 여기서 중요한 점은 복잡한 데이터 저장과 부분 업데이트, *참조 무결성을 지원해야 할 경우에는 Room을 사용하는 것 좋고, Datastore는 소규모 단순 데이터를 저장하는데 적합하며 업데이트나 *참조 무결성은 지원하지 않습니다.
2️⃣DataStore
Jetpack Datastore는 *프로토콜 버퍼를 사용하여 키-값 쌍 또는 유형이 지정된 객체를 저장할 수 있는 데이터 저장소 솔루션 입니다. Datastore는 Kotlin Coroutine 및 Flow를 사용하여 비동기적이고 일관된 트랜잭션 방식으로 데이터를 저장합니다.
Datastore 유형
Preferences Datastore : 데이터를 키-값 쌍으로 구성하여 저장할 수 있고, 미리 정의된 스키마가 필요하진 않지만 *type safety를 제공하지 않습니다.
Proto Datastore : 사용자가 정의한 데이터(custom data type)를 저장하고 *프로토콜 버퍼를 사용해 스키마를 정의해야 하지만 *type safety를 제공합니다.
Datastore 장점
- Proto Datastore을 사용하는 경우 *type safety를 제공합니다.
- 비동기 API로 *Coroutine Flow를 사용하여 읽고, 쓰기에 대한 비동기 처리가 가능합니다.
- 기본적으로 Datastore는 작업을 Dispatchers.IO에 전달해 Dispatchers.IO가 관리하는 *스레드풀(Thread Pool) 내의 스레드의 부하 상황에 맞춰 작업을 배분하기 때문에 UI Thread에서 호출해도 안전합니다.
- Error 신호를 보낼 수 있고, 런타임 예외로 부터 안전합니다.
- 일관성을 보장하는 트랜잭션 API를 가지고 있습니다.
- SharedPreference를 Datastore로 *migration 할 수 있어서 작업 중인 프로젝트에서 대체하여 사용하기 편리합니다.
아래의 SharedPreference를 사용할 때 발생할 수 있는 문제점들을 보완하는 것을 확인할 수 있습니다.
- 실제 XML 파일 I/O 작업을 하는 것이기 때문에 UI Thread에서 작업할 경우 안전하지 않다.
- Runtime Exception으로 부터 안전하지 않다.
- XML 파일이기에 외부에서 쉽게 파일을 읽을 수 있다. (Datastore도 동일)
- 비동기 API를 제공하지만 Listener를 통해서만 값을 읽을 수 있다.
- *type safety를 제공하지 않는다.
예제
현재 제가 구현하려는 것은 문자열을 저장하려는 것이 목적이기 때문에 Preferences DataStore를 사용하는 예제를 구현해보겠습니다.
1.
2.
3.
4.
5.
*참조 무결성 : 기본키와 외래키외래 키 간의 관계가 항상 유지되는 것을 보장합니다. 참조되는 테이블의 행을 이를 참조하는 외래 키가 존재하는 한 삭제될 수 없고, 기본키도 변경될 수 없습니다. 이를 통해 사용자의 실수로 관련 데이터가 삭제되거나 수정되는 것을 막아줍니다.
*프로토콜 버퍼 : 구조화된 데이터를 직렬화하기 위한 Google의 언어와 플랫픔에 중립적이고 확장 가능한 메커니즘입니다. XML을 생각할 수 있지만 더 가볍고 빠르고 간단합니다. 데이터를 구조화하는 방법을 한 번 정의한 다음, 생성된 특수 코드를 사용해 다양한 데이터 스트림과 다양한 언어를 사용해 구조화된 데이터를 쉽게 쓰고 읽을 수 있습니다. 쉽게 말해서 데이터를 직렬화 하기 위한 메커니즘이라고 보면 됩니다.
*type safety : Type Check를 할 수 있어 Runtime에서 문제가 발생하는 것이 아닌 컴파일 단계에서 문제를 잡을 수 있도록 해줍니다.
*스레드풀(Thread Pool) : 작업 처리에 사용되는 스레드를 제한된 개수만큼 정해놓고 작업 큐에 들어오는 작업들을 하나씩 스레드가 맡아 처리하여 작업처리 요청이 폭증되어도 앞에서 말했듯 스레드의 개수를 제한하여 처리하기 때문에 스레드의 전체 개수가 늘어나지 않아 시스템 성능이 급격히 저하되지 않도록 합니다.
*migration : 한 운영환경으로 부터 좀 더 낫다고 여겨지는 다른 운영환경으로 옮겨가는 과정을 말합니다.
*Coroutine Flow : 데이터를 발행하는 발행자가 데이터의 소비자에게 지속적으로 데이터를 전달(데이터 스트림)하며, Coroutine 상에서 데이터가 변경되면 이벤트를 발생시켜 데이터를 계속해서 전달할 수 있도록 하는 프로그래밍 방식인 반응형 프로그래밍을 지원하기 위한 구성요소입니다.
'Android > Android의 모든 것' 카테고리의 다른 글
👋Android의 모든 것 : 1️⃣Room, 2️⃣예제(Koin, Room) (0) | 2022.03.28 |
---|---|
👋Android의 모든 것 : 1️⃣Lottie에 대해서 (0) | 2022.03.25 |
👋Android의 모든 것 : 1️⃣안드로이드의 애니메이션의 모든 것 (0) | 2022.03.17 |
👋Android의 모든 것 : 1️⃣BottomSheetDialogFragment, 2️⃣Bottomsheetbehavior (0) | 2022.03.17 |
👋Android의 모든 것 : 1️⃣Activity 상태 변경 처리, 2️⃣Task & Back Stack, 3️⃣Parcelable 및 Bundle (0) | 2022.03.16 |