원문
- medium.com/swlh/welcome-datastore-good-bye-sharedpreferences-fdeb831a1e58
- developer.android.com/topic/libraries/architecture/datastore
원문을 읽으면서 제가 공부하려고 번/의역한 것 입니다.
아직 블로그 반말을 써야할지 존댓말을 써야할지...안정해서 혼란스러운점 양해부탁드립니다...ㅋㅋㅋ
이제부터 그냥 존댓말 쓸게요. 나혼자 주저리 리뷰글이아니라면...
Proto DataStore가 Preferences Data Store와 다른 점을 알아보려면 제 이전 글을 읽어주세요!
- [Android] Preferences DataStore 사용법과 개념
Proto DataStore 간단 개요!
- 사용자가 정의한 형식의 데이터(Custom data types)를 저장하고 가져옵니다.
- Protocol Buffers를 이용해 스키마를 정의합니다.
- 작고, 빠르고, 단순하고, XML을 비롯한 다른 데이터 형식들보다 덜 모호합니다.
Protocol Buffers는 뭔데요?
Protocol Buffers는 구글의 *데이터를 직렬화 하기위한 메커니즘입니다. 언어 중립적/플랫폼 중립적/확장 가능하다는 특징이있습니다.
Protocol Buffers는 현재 Java, Python, Objective-C, 그리고 C++에서 생선된 코드를 지원합니다.
*데이터의 직렬화(serialization): 메모리의 객체를 디스크에 저장하거나, 네트워크를 통해 전송되는 형식으로 변환하는 작업.
*역직렬화(deserialization): 디스크에 저장된 데이터를 읽거나, 네트워크를 통해 전송된 데이터를 받아 메모리에 재구축하는 것.
- 출처: 118k.tistory.com/740
1.Gradle Settings
Proto DataStore를 사용하려면 아래의 dependency가 필요합니다. (*protobuf 내용 추가완료!)
plugins {
id 'com.android.application'
id 'kotlin-android'
id "com.google.protobuf" version "0.8.12"
}
dependencies {
implementation "androidx.datastore:datastore-core:1.0.0-alpha01"
// Protobuf
implementation "com.google.protobuf:protobuf-javalite:3.10.0"
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.10.0"
}
// Generates the java Protobuf-lite code for the Protobufs in this project. See
// https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
// for more information.
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
}
}
}
}
2. 스키마 정의하기app/src/main/proto
경로에 스키마를 정의해야합니다. 우리는 user_info.proto
라는 파일을 app/src/main/proto
경로 아래에 만들어 보겠습니다. 프로토 스키마에 관해 더 알아보고 싶다면, 이 페이지를 참고해주세요.
syntax = "proto3";
option java_package = "본인 패키지 명";
option java_multiple_files = true;
message UserSettings {
enum BgColor {
COLOR_WHITE = 0;
COLOR_BLACK = 1;
}
BgColor bgColor = 1;
}
위의 스키마를 정의한 후 Gradle Project를 Rebuild해줍니다.
3. Proto 클래스를 위한 Serializer 만들기
프로토 파일에 정의한 타입 T
의 Serializer<T>
를 implment하는 클래스를 만들어 볼겁니다. 즉 UserSettings
가 타입이 됩니다. 이 Serializer 클래스는 DataStore에게 이 타입의 클래스를 어떻게 읽고, 써야하는지 알려줍니다.
object ProtoSettingsSerializer : Serializer<UserSettings> {
override fun readFrom(input: InputStream): UserSettings {
try {
return UserSettings.parseFrom(input)
} catch (ex: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", ex)
}
}
override fun writeTo(t: UserSettings, output: OutputStream) {
t.writeTo(output)
}
}
4. Proto DataStore 만들기Context.createDataStore()
를 이용하여 DataStore<UserSettings>
의 인스턴스를 만들어 볼 것입니다. filename
파라미터는 DataStore가 데이터를 저장하기 위해 어떤 파일을 사용해야하는지 알려줍니다. 그리고 serializer
파라미터는 Serializer 클래스의 이름입니다. 우리가 앞서 정의한 ProtocolSettingsSerializer를 사용해주면 되겠죠.
아래 코드는 DataStore를 생성하는 부분입니다. 후에 읽기/쓰기시 다루기 편하도록 ProtoSettingsManager
라는 클래스를 만들었습니다.
class ProtoSettingsManager(val context: Context) {
private val dataStore: DataStore<UserSettings> =
context.createDataStore(fileName = "user_settings.pb", serializer = ProtoSettingsSerializer)
}
5. Proto DataStore에서 데이터 읽기
이전 Preferences DataStore에 관한 글에서 다루었던 것 처럼, DataStore.data
를 이용해 저장된 오브젝트에 대한 Flow
를 가져옵니다. 아래 코드에서 userSettingsFLow 변수가 UserSettings
객체에 대한 Flow
를 보냅니다.
class ProtoSettingsManager(val context: Context) {
private val dataStore: DataStore<UserSettings> =
context.createDataStore(fileName = "user_settings.pb", serializer = ProtoSettingsSerializer)
val userSettingsFlow: Flow<UserSettings> = dataStore.data.catch { ex ->
if (ex is IOException) {
emit(UserSettings.getDefaultInstance())
} else {
throw ex
}
}
}
6. Proto DataStore에 쓰기
Proto DataStore는 updateData()
라는 메소드를 통해 저장된 오브젝트를 업데이트 할 수 있습니다. updateColor()
의 인자인 UserSettings.BgColor
역시 user_info.proto
에 enum으로 정의되어 있었죠.
class ProtoSettingsManager(val context: Context) {
private val dataStore: DataStore<UserSettings> =
context.createDataStore(fileName = "user_settings.pb", serializer = ProtoSettingsSerializer)
val userSettingsFlow: Flow<UserSettings> = dataStore.data.catch { ex ->
if (ex is IOException) {
emit(UserSettings.getDefaultInstance())
} else {
throw ex
}
}
suspend fun updateColor(bgColor: UserSettings.BgColor) {
dataStore.updateData { userSetting ->
userSetting.toBuilder().setBgColor(bgColor).build()
}
}
}
* Activity에서 DataStore를 사용하는 방법은 이 전글과 동일합니다.
DataStore에 대한 나의 생각
Prefence DataStore는 SharedPreference를 대체하기 적절해보이긴하는데... Proto DataStore는 타입을 보장해주긴 하지만 스키마도 만들어야해서 좀 더 구현하기 귀찮을 것 같다. 하지만 구글 문서 예제처럼 "설정" 값 전체를 하나의 객체로 묶어서 저장하고 업데이트할때 좋을듯....? Key-Value 쌍으로 하기엔 너무 많은것들 같은거? 다음 앱에 한번 써봐야지 ㅎㅎ
문서에는 더 많은 데이터 셋이나, 복잡한 데이터 같은 경우에는 Room에 저장해라고 권고하고있다.
'프로그래밍 > Android' 카테고리의 다른 글
[안드로이드] 예제로 알아보는 Foreground Service (0) | 2020.10.15 |
---|---|
[안드로이드] 서비스(Service)에 대해 알아보자 (0) | 2020.10.13 |
[Android] Preferences DataStore 사용법과 개념 (0) | 2020.10.09 |
[안드로이드] FragmentStateAdapter / FragmentPagerAdapter 차이, 사용법 (0) | 2020.10.05 |
[안드로이드] Checkbox의 Style을 코드상에서 지정해 주는 방법 (set check box style programmatically) (0) | 2020.09.29 |