본문
DataStore 개념 및 실습
컴퓨터/이론: 안드로이드 2020. 12. 13. 14:32
도입
이번 포스팅에서는 DataStore
에 대해 정리할 예정이다.
DataStore 개념 및 특징
- Jetpack에서 제공하는 key-value 데이터 저장소
- Coroutine, Flow을 지원해 데이터를 asynchronously, consistently, transactionally하게 저장 할 수 있다.
DataStore VS SharedPreference
DataStore의 종류
DataStore는 아래와 같이 2가지 종류가 있다.
Preferences DataStore
keys
를 통한 데이터 접근, type safety 제공 X
// Preferences DataStore (SharedPreferences like APIs)
dependencies {
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha05"
}
// Alternatively - use the following artifact without an Android dependency.
dependencies {
implementation "androidx.datastore:datastore-preferences-core:1.0.0-alpha05"
}
Proto DataStore
custom data type
을 통한 데이터 접근
(Protocol buffers에 schema 저장 필요), type safety 제공 O
// Typed DataStore (Typed API surface, such as Proto)
dependencies {
implementation "androidx.datastore:datastore:1.0.0-alpha05"
}
// Alternatively - use the following artifact without an Android dependency.
dependencies {
implementation "androidx.datastore:datastore-core:1.0.0-alpha05"
}
실습
Preferences DataStore
// Read Preferences DataSource
fun setRecentStayedPackageByPrefDataStore(
componentActivity: ComponentActivity,
packageName: String
) {
// Create Preferences DataStore
val preferenceDataStore = componentActivity.createDataStore(name = "testSettings")
val recentStayPackageKey = preferencesKey<String>(KEY_RECENT_STAYED_PACKAGE)
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
preferenceDataStore.edit { testSettings ->
testSettings[recentStayPackageKey] = packageName
}
}
}
// Write to a Preferences DataStore
fun getRecentStayedPackageByPrefDataStore(
componentActivity: ComponentActivity
): String? {
// Create Preferences DataStore
val preferenceDataStore = componentActivity.createDataStore(name = "testSettings")
val recentStayPackageKey = preferencesKey<String>(KEY_RECENT_STAYED_PACKAGE)
return runBlocking {
preferenceDataStore.data
.map { preferences -> preferences[recentStayPackageKey] }
.firstOrNull()
}
}
Proto DataStore
// Apply plugin
// @see https://jitpack.io/p/google/protobuf-gradle-plugin
plugins {
id "com.google.protobuf" version "0.8.12"
}
dependencies {
implementation "com.google.protobuf:protobuf-javalite:3.11.0"
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.11.0"
}
generateProtoTasks {
all().each { task ->
task.builtins {
java {
option 'lite'
}
}
}
}
}
// app/srs/main/proto/user_pref.proto
syntax = "proto3";
option java_package = "$YourPackageName";
option java_multiple_files = true;
message UserPreferences {
string recent_stayed_package = 1;
}
// Serialize protoBuffer
object DataStoreSerializer : Serializer<UserPreferences> {
override val defaultValue: UserPreferences = UserPreferences.getDefaultInstance()
override fun readFrom(input: InputStream): UserPreferences {
try {
return UserPreferences.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}
override fun writeTo(
t: UserPreferences,
output: OutputStream
) = t.writeTo(output)
}
// Read from a proto DataStore
fun setRecentStayedPackageByProtoDataStore(
componentActivity: ComponentActivity,
packageName: String
) {
val protoDataStore: DataStore<UserPreferences> = componentActivity.createDataStore(
fileName = "user_pref.pb",
serializer = DataStoreSerializer
)
componentActivity.lifecycleScope.launch(Dispatchers.IO) {
protoDataStore.updateData { currentUserPref ->
currentUserPref.toBuilder()
.setRecentStayedPackage(packageName)
.build()
}
}
}
// Write to a proto DataStore
fun getRecentStayedPackageByProtoDataStore(componentActivity: ComponentActivity): String {
val protoDataStore: DataStore<UserPreferences> = componentActivity.createDataStore(
fileName = "user_pref.pb",
serializer = DataStoreSerializer
)
return runBlocking {
protoDataStore.data
.map { currentUserPref -> currentUserPref.recentStayedPackage }
.first()
}
}
DataStore in synchronous code
Synchronous code를 제공하기 위해 코루틴의 runBlocking
사용 가능
추가로 아래 스냅핏을 통해 메모리 캐시에 로드 후 runBlocking
사용 권고
(빠르게 사용하기 위함)
override fun onCreate(savedInstanceState: Bundle?) {
lifecycleScope.launch {
dataStore.data.first()
}
}
Reference
https://developer.android.com/topic/libraries/architecture/datastore#typed-datastore
https://developers.google.com/protocol-buffers/docs/javatutorial
'컴퓨터 > 이론: 안드로이드' 카테고리의 다른 글
Unit Test 기본 실습 (0) | 2020.12.20 |
---|---|
Unit Test 개념 및 Lifecycle (0) | 2020.12.19 |
Gradle implementation (0) | 2020.04.02 |
generated Folder 란? (0) | 2020.03.16 |
minSdkVersion, targetSdkVersion, compileSdkVersion 정리 (0) | 2020.03.14 |
댓글