DEV Community

kaede
kaede

Posted on • Edited on

Android 基礎 -- Part 05 Datastore に保存するための Repository の save メソッドを作成する

why

ステートに持った値を保存したい。
DB にはまだ繋がず、とりあえず Datastore に保存する。

Gauge のアプリでレスポンスを シナリオデータストアに入れていたように
Android でもデータストアに入れる。

https://www.youtube.com/watch?v=aQyphCXeVHg&list=PLgAI_5b_7BdRaBPAD5RMrzjoSwefDXpkw&index=7

SharedPreference という名前で使えるらしい。


Datastore Preferences 1.0 をインポート

dependencies { //... implementation 'androidx.datastore:datastore-preferences:1.0.0' } 
Enter fullscreen mode Exit fullscreen mode

App の build.gradle の dependecies の implementation で
androidx の datastore の datastore-preferences:1.0.0
これを書き、 sync してインストールする


Repository (Driver) を作成して Datastore に書き込めるようにする

https://www.youtube.com/watch?v=uvAbY38CNXU&list=PLgAI_5b_7BdRaBPAD5RMrzjoSwefDXpkw&index=8

コンポーザブルからは呼び出すだけで、処理担当を分ける。
実際にデータを書き込む処理は、Repository に書く。
クリーンアーキテクチャで言う、Driver 相応だろう。

現状、アプリのディレクトリ構造として

  • screen / edit / EditNoteScreen.kt
  • ui / theme /
  • MainActivity.kt
  • NoteApp.kt

この構造になっている。

ここに package として repository / を追加する。
その中にインターフェースとして NoteRepository を作る。

Drive というより、インターフェースだから Port っぽいな


インターフェースである reposotiry / NoteRepository で save と load を定義する

実装する前のインターフェースとして、クリーアーキテクチャで言う
Port のようなものを作る。実装と呼び出し先を繋げるものだ。

ここでは save と load を作る。

package com.example.hellojetpack.repository interface NoteRepository { suspend fun save(body: String) suspend fun load(): String } 
Enter fullscreen mode Exit fullscreen mode

インターフェースを TODO で実装する repository / datastore / DatastoreNoteRepository で save と load を実装する。

とりあえず TODO で実装する。

実際の実装クラスを書く。
クリーンアーキテクチャでいう Driver のパッケージに書くものだ。

MokeLab さんのやり方では Repository パッケージの中に
さらに datastore パッケージを作って、中に書くらしい。

なので、先ほど作った repository / のなかに datastore / を作って、その中に DatastoreNoteRepositrory.kt を作った。

class DatastoreNoteRepository: NoteRepository { override suspend fun save(body: String) { TODO("Not yet implemented") } override suspend fun load(): String { TODO("Not yet implemented") } } 
Enter fullscreen mode Exit fullscreen mode

中身は、NoteRepository のインターフェースを
implement members してガワを作った。


DatastoreNoteRepository のために Context に noteStore というプロパティを用意する。

https://www.youtube.com/watch?v=uvAbY38CNXU&list=PLgAI_5b_7BdRaBPAD5RMrzjoSwefDXpkw&index=8

この Android X のデータストアを使うためには Android の Context を使って、その中にプロパティを用意する必要があるらしい。

Context とは、React における Redex のような、どのコンポーザブルからでも読み書きのできる置き場所だと解釈する。

https://developer.android.com/topic/libraries/architecture/datastore?hl=ja#preferences-create

Kotlin ファイルの最上位、つまり一番最初にインスタンスが一度作られるらしい。そしてシングルトンで保持できるらしい。

https://e-words.jp/w/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%88%E3%83%B3.html

シングルトンとは、一つしかインスタンスが作られないことで、つまり共通データにアクセスされるコンテキストのことだと解釈する。

import android.content.Context import androidx.datastore.preferences.core.Preferences val Context.noteStore: DataStore<Preferences> by preferencesDataStore( "note" ) 
Enter fullscreen mode Exit fullscreen mode

Android Context のなかに noteStore と言うプロパティを作成
型は先ほど依存に追加した Android X DataStore の Preferences とする。
これで Gauge で言う Scenario Datastore のように
Android の Preference Datastore として
キーバリューストアが使えるようになると解釈した。


PreferencesDatastore のための Preference Key を用意する

https://youtu.be/uvAbY38CNXU?t=200

val BODY_KEY = stringPreferenceKey("body") 
Enter fullscreen mode Exit fullscreen mode

データストアは キーバリュー ストアなので
次はキーを作る。
Preference Datastore を作ったので、対応する
Preferecne Key を作った。


Context.noteStore に Repository の save メソッドで引数のキーと中身の値が入るようにする。

val Context.noteStore: DataStore<Preferences> by preferencesDataStore( "note" ) class DatastoreNoteRepository: NoteRepository { override suspend fun save(body: String) { TODO("Not yet implemented") } override suspend fun load(): String { TODO("Not yet implemented") } } 
Enter fullscreen mode Exit fullscreen mode

現状、Preference の Datastore を使って
Context に noteStore プロパティを生やしている。

save メソッドの中身には何もない。

class DatastoreNoteRepository( private val context: Context ): NoteRepository { override suspend fun save(body: String) { TODO("Not yet implemented") } } 
Enter fullscreen mode Exit fullscreen mode

コンストラクタ インジェクションで
クラス生成時に一度だけ context インスタンスができるようにする。

 override suspend fun save(body: String) { context.noteStore.edit { pref -> pref[BODY_KEY] = body } } 
Enter fullscreen mode Exit fullscreen mode

引数の body を
ストアの BODY_KEY と言うキーのバリューとして入れる。

Top comments (0)