기존의 SharedPreferences
의 단점을 보안하여 만들어진 Datastore
를 사용해 보려고 한다.
우선 DataStore
는 두 가지의 기능을 제공한다.
SharedPreferences
와 동일하게 Key-value
형태로 데이터를 저장하고 사용하며 타입 안정성을 제공하지 않는다.프로토콜 버퍼 : 구조화된 데이터를 직렬화하기 위한 기술
다양한 대량의 데이터를 저장할 때에는 내부 DB를 이용한 Room
과 같은 라이브러리를 활용하여 저장하는 것이 더 효율적일 것이다. 하지만 간단한 데이터를 저장하는데 Room
을 사용하는 것은 많은 비용을 필요로 할 것이다. 이때 Datastore
를 사용하는 것이 좋아 보인다.
Preferences
, Proto
Datastore를 사용해서 버튼을 클릭했을 때 카운트를 저장하는 간단한 앱을 만들어 본다.
dependencies {
implementation "androidx.datastore:datastore-preferences:1.0.0"
}
data class
를 만들어 준다. 추후 매핑 작업을 진행할 것이다.data class UserPreferences(val clickCount: Int)
Repository
를 사용할 것이다.
data class
와 매핑할 PreferencesKeys
를 만들어준다.
getUserPreferences()
를 통해 해당 값을 가져갈 때 오류가 발생하면 IOException
이 발생하고, 기본 값을 방출하게 되어있다. mapUserPreferences()
를 사용해 data class
로 변환해 준다.
updatePreferencesClickCount()
함수를 이용하여 값을 update 해준다.
최초에 저장된 값을 불러오고 버튼 클릭 이벤트가 발생했을 때 값을 업데이트해주고 있다.
XML
에서 onClick
이벤트를 받는 방법 및 저장된 값을 사용하는 방법이다.
Preferences Datastore
를 싱글톤으로 제공할 수 있게 생성해준다.
databinding
설정을 하고 ViewModel
를 생성해 준다.
Preferences Datastore
를 View
에 적용하는 법까지 알아보았으니 같은 기능을 구현할 때 설정하는 방법을 간단히 알아보자.
plugin
에 id "com.google.protobuf" version "0.8.17"
를 추가해준다.
dependencies
에 아래 두 가지를 추가해 준다.
implementation "androidx.datastore:datastore-core:1.0.0"
implementation "com.google.protobuf:protobuf-javalite:3.18.0"
파일 최하단에 아래 코드를 작성해 주면 설정은 끝이다.
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.14.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'
}
}
}
}
}
Project로 변경해 준다. 그다음 app/src/main 하위에 proto directory를 만들어준다. .proto
파일을 하나 만들어 준다.
syntax = "proto3";
option java_package = "com.example.datastoreexample";
option java_multiple_files = true;
message UserProto {
int32 clickCount = 1;
}
message 키워드를 통해 정의하며 각 요소는 여러 가지 타입을 가질 수 있다. 또한 각 요소에 1부터 차례로 할당할 수 있다.
프로토콜 버퍼 문서 참고
작성한 뒤 Build
를 하게 되면 파일이 생성되어 있는 것을 확인할 수 있다.
Datastore
에서 읽고 쓰기 위해 serializer를 구현해야 합니다.
데이터를 읽을 때 오류가 발생하면 IOException
이 발생하고, 기본 값을 방출하게 되어있다.
updateData()
함수를 통해 값을 업데이트 있다.
아까 만든 Serializer
를 사용해 DataStore
를 생성해 준다.
나머지 적용 방식은 이전과 똑같다.
Datastore
의 두 가지 방식을 간단하게 구현해 봤다. Proto Datastore
를 사용하기 위해선 좀 더 설정해야 할 부분이 많지만 타입 안정성을 제공하기 때문에 좀 더 많이 사용되지 않을까 싶다.