관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] 새로운 저장소 Jetpack DataStore (feat. Sharedpreferences 를 대체) 본문

안드로이드/코틀린 & 아키텍처 & Recent

[안드로이드] 새로운 저장소 Jetpack DataStore (feat. Sharedpreferences 를 대체)

막무가내막내 2020. 9. 3. 12:37
728x90

 

[2021-04-14 업데이트]

 

 

안드로이드 Jetpack 에서 DataStore 가 나왔습니다. 이에 대해 문서를 보며 확실히 공부도 하고 영어도 해석할 겸 포스팅합니다. (아직 한국어 나오기전입니다)

Jetpack DataStore는 데이터 스토리지 솔루션이며 key-value pairs 나 objects 타입을 protocol buffers로 저장이 가능합니다. DataStore는 코틀린 코루틴과 Flow 를 사용하여 asynchronously, consistently, transactionally 하게 데이터를 저장합니다. 

만약 현재 Sharedpreferences 를 사용중이라면 DataStore로 migrating를 고려합시다.

Note: If you need to support large or complex datasets, partial updates, 
or referential integrity, consider using Room instead of DataStore. 
DataStore is ideal for small, simple datasets and 
does not support partial updates or referential integrity.

복잡하고 큰 용량의 데이터를 사용하면 Room 을 사용합시다.

 

 


Preferences DataStore and Proto DataStore

DataStore는 두 가지 다른 구현을 갖고있습니다. Preferences DataStore and Proto DataStore 입니다.

1. Preferences DataStore 는 key를 사용하여 데이터에 저장 및 접근을 합니다. 이 구현체는 스키마를 미리 정의할 것을 요구하지 않고 type safety 또한 제공하지 않습니다.

2. Photo DataStore 는 커스텀 데이터 타입의 인스턴스 데이터를 저장하는데 사용합니다. 이 구현체는 protocol buffers를 사용하여 schema 를 정의하는게 필요하고 type safety 를 제공합니다.

 

 


Setup

build.gradle 에 다음을 추가하여 사용할 수 있습니다.

dependencies {
    // Preferences DataStore
    implementation "androidx.datastore:datastore-preferences:1.0.0-alpha01"


    // Proto DataStore
    implementation  "androidx.datastore:datastore-core:1.0.0-alpha01"
}

 

 


 

Store key-value pairs with Preferences DataStore

Preferences DataStore 는 DataStore 와 Preferences class 들을 사용하여 심플한 key-value 쌍으로 디스크에 보존합니다. 

 

Create a Preferences DataStore

Context.createDataStore() 확장 함수를 사용해 DataStore<Preferences> 인스턴스를 생성합니다. Preferences DataStore의 name은 필수 파라미터 입니다.

val dataStore: DataStore<Preferences> = context.createDataStore(
  name = "settings"
)

 

Read from a Preferences DataStore

Preferences DataStore 는 schema를 미리 정의하지 않기 때문에, Preferences.preferencesKey() 를 사용하여 DataStore<Preferences> 인스턴스에 저장이 필요한 key 와 각각의 value를 정의해줘야 합니다. 그 다음, Flow를 사용하여 적절한 value 를 expose 해주기 위해 DataStore.data 프로퍼티를 사용합니다.

val EXAMPLE_COUNTER = preferencesKey<Int>("example_counter")
val exampleCounterFlow: Flow<Int> = dataStore.data
  .map { preferences ->
    // No type safety.
    preferences[EXAMPLE_COUNTER] ?: 0
}

 

 

Write to a Preferences DataStore

Preferences DataStore 는 edit() 함수를 제공하고 transactionally 하게 DataStore에 데이터를 업데이트 시켜줍니다. 함수의 transform parameter 는 사용자가 값 업데이트가 필요할 때마다 코드의 block을 허용합니다. transform block 안에 있는 모든 코드는 single transaction으로 다루어집니다.

suspend fun incrementCounter() {
  dataStore.edit { settings ->
    val currentCounterValue = settings[EXAMPLE_COUNTER] ?: 0
    settings[EXAMPLE_COUNTER] = currentCounterValue + 1
  }
}

 

 


Store typed objects with Proto DataStore

Proto DataStore 구현체는 object 타입을 디스크에 저장하기 위해 DataStore와 protocol buffers 를 사용합니다.

 

Define a schema

Proto DataStore 는 app/src/main/proto/ 디렉토리 안의 proto file 의 스키마를 미리 정의해야합니다. 이 스키마는 Proto DataStore 에 저장할 object 타입을 정의합니다. proto schema 정의에 대해 더 공부하고 싶다면 다음을 참고하면 됩니다. protobuf language guide.

syntax = "proto3";

option java_package = "com.example.application";
option java_multiple_files = true;

message Settings {
  int example_counter = 1;
}
Note: The class for your stored objects is generated at compile time 
from the message defined in the proto file. Make sure you rebuild your project.

 

 

Create a Proto DataStore

Proto DataStore 를 생성하고 Typed Objects 를 저장하는데 두 가지 단계가 있습니다.

1. 클래스가 Serializer<T> 를 implements 해야합니다. 이 때 T 는 proto file 안의 타입을 정의해주면 됩니다. serializer class 는 DataStore 가 사용자의 데이터 타입을 어떻게 읽고 쓸지 알려줍니다.

2. Context.createDataStore() 확장 함수를 사용하여 DataStore<T> 인스턴스를 생성합니다. 이 때 T 는 proto file 안의 타입입니다. fileName 파라미터는 DataStore 에게 저장할 데이터를 위해 사용할 file 을 알려주고 serializer 파라미터는 1번 단계에서 정의한 serializer 클래스의 이름을 DataStore에게 알려줍니다. 

object SettingsSerializer : Serializer<Settings> {
  override fun readFrom(input: InputStream): Settings {
    try {
      return Settings.parseFrom(input)
    } catch (exception: InvalidProtocolBufferException) {
      throw CorruptionException("Cannot read proto.", exception)
    }
  }

  override fun writeTo(
    t: Settings,
    output: OutputStream) = t.writeTo(output)
}

val settingsDataStore: DataStore<Settings> = context.createDataStore(
  fileName = "settings.pb",
  serializer = SettingsSerializer
)

 

 

Read from a Proto DataStore

저장된 object로부터 적절한 프로퍼티의 플로우를 제공하기 위해 DataStore.data 를 사용합니다.

val exampleCounterFlow: Flow<Int> = settingsDataStore.data
  .map { settings ->
    // The exampleCounter property is generated from the proto schema.
    settings.exampleCounter
  }

 

 

Write to a Proto DataStore

Proto DataStore는 저장된 object를 transactionally 하게 업데이트 해주는 updateData() 함수를 제공합니다. updataData() 는 데이터 타입의 인스턴스로 데이터의 현재 상태를 주고 data 를 atomic read-write-modify operation 를 통해 transactionally 하게 데이터를 업데이트 해줍니다.

suspend fun incrementCounter() {
  settingsDataStore.updateData { currentSettings ->
    currentSettings.toBuilder()
      .setExampleCounter(currentSettings.exampleCounter + 1)
      .build()
    }
}

 

 


SharedPrefernces 와 비교하여 좋은 옵션들이 추가되었습니다.  아직 코루틴을 예전에 한번보고 자세히 공부하지않아 Flow는 잘 모르는데 코루틴을 밀어주는게 확실히 보이는 것 같습니다.

 

 

댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!

 

[참고 및 출처]

android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html

 

Prefer Storing Data with Jetpack DataStore

Posted by Florina Muntenescu , Android Developer Advocate, Rohit Sathyanarayana, Software Engineer Welcome Jetpack DataStore, now in ...

android-developers.googleblog.com

developer.android.com/topic/libraries/architecture/datastore

 

DataStore  |  Android 개발자  |  Android Developers

Jetpack DataStore is a data storage solution that allows you to store key-value pairs or typed objects with protocol buffers. DataStore uses Kotlin coroutines and Flow to store data asynchronously, consistently, and transactionally. If you're currently usi

developer.android.com

codelabs.developers.google.com/codelabs/android-preferences-datastore/#0

 

Working with Preferences DataStore

What is DataStore? DataStore is a new and improved data storage solution aimed at replacing SharedPreferences. Built on Kotlin coroutines and Flow, DataStore provides two different implementations: Proto DataStore, that stores typed objects (backed by prot

codelabs.developers.google.com

codelabs.developers.google.com/codelabs/android-proto-datastore/#0

 

Working with Proto DataStore

What is DataStore? DataStore is a new and improved data storage solution aimed at replacing SharedPreferences. Built on Kotlin coroutines and Flow, DataStore provides two different implementations: Proto DataStore, that lets you store typed objects (backed

codelabs.developers.google.com

 

728x90
Comments