Android Proto DataStore:SharedPreferences から切り替える価値はありますか?
数年前、Google は、実証済みの SharedPreferences に代わる DataStore を発表しました。
アプリケーションで SharedPreferences を使用している、または使用したことがある場合は、切り替えを検討しているかもしれません。しかし、すべてのことと同様、ここでの主な疑問は、開発コストはいくらになるのかということです。
DataStore を使用するメリットはありますが、Proto DataStore のみです。 タイプ セーフティを提供しながらオブジェクトを保存できます。
Proto DataStore のドキュメントを見ると、それが少し古く、操作する際の重要な手順がいくつか欠けていることがわかります。そのため、この記事では、Proto DataStore をアプリケーションに統合する方法を説明し、Proto DataStore を使用するのがそれほど面倒ではないことを示します。
データストアとは何ですか?
Jetpack DataStore には 2 つのバリエーションがあります。
- 設定データストア
- プロト データストア
1 つ目については、SharedPreferences と類似しており、広く取り上げられているため、説明しません。それでは、Proto DataStore の Proto が何を意味するのかを理解しましょう。
Proto は、Google がプロトコル バッファーを表すために選んだ名前です。これらは、構造化データのシリアル化に役立つ (Google の) メカニズムです。これらはコーディング言語に固有のものではなく、一般に、操作するデータのタイプを定義すると、データの読み取りと書き込みに役立つコードが生成されます。
✋ この記事では Proto 3 バージョンを使用します。
その定義はどのようになりますか?
message MyItem {
string itemName = 1;
int32 itemId = 2;
}
まず、message キーワードを使用してオブジェクトを定義します。その中に、そのオブジェクトに関連付けられたフィールドをリストします。各フィールドの末尾の番号はフィールド自体を識別するために使用され、一度設定され、 オブジェクトが使用されている場合は変更できません。 .
しかし、.proto ファイルに複数のオブジェクトを含めたい場合はどうすればよいでしょうか?オブジェクトが相互に関連していると仮定すると、メッセージ オブジェクトを追加するだけでこれを行うことができます。
message MyItem {
string itemName = 1;
int32 itemId = 2;
}
message MyListOfItems {
repeated MyItem items = 1;
}
上記で定義した MyItem オブジェクトに依存する別のメッセージ オブジェクトを追加していることに注意してください。オブジェクトのリストを定義したい場合は、繰り返しを使用する必要があります。 キーワード。
Proto DataStore のセットアップ方法
まず、次の依存関係をアプリケーション レベルの build.gradle に追加する必要があります。
implementation "androidx.datastore:datastore-preferences:1.0.0"
implementation "com.google.protobuf:protobuf-javalite:3.18.0"
次に、プロジェクト内に proto ディレクトリを作成する必要があります。このディレクトリは、プロジェクト構造内の Java フォルダの兄弟である必要があります。
proto ディレクトリ内に .proto ファイルを作成します。このファイルは、Proto DataStore に保存するデータ タイプを生成する役割を果たします。
proto ディレクトリ内に、.proto 拡張子を持つファイルを作成します。 .proto ファイルには、Todo リスト (他に何か?) を表すオブジェクトが保持されます。したがって、ファイルを todo.proto という名前にします。 次のようになります:
syntax = "proto3";
option java_package = "com.yourPackageName.todo";
option java_multiple_files = true;
message TodoItem {
string itemId = 1;
string itemDescription = 2;
}
message TodoItems {
repeated TodoItem items = 1;
}
2 つのメッセージ オブジェクトをどのように定義したかに注目してください。
<オル>次に、TodoItem と TodoItem のクラスが生成されるようにプロジェクトをビルドします。
データ オブジェクトを定義したら、それらをシリアル化するクラスを作成する必要があります。このクラスは、オブジェクトの読み取り/書き込み方法を DataStore に指示します。
// 1
object TodoItemSerializer: Serializer<TodoItems> {
// 2
override val defaultValue: TodoItems = TodoItems.getDefaultInstance()
// 3
override suspend fun readFrom(input: InputStream): TodoItems {
try {
return TodoItems.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}
// 3
override suspend fun writeTo(
t: TodoItems,
output: OutputStream
) = t.writeTo(output)
}
このクラスの内容を確認してみましょう。
<オル>データ型とシリアライザーを含む .proto ファイルがあるので、次のステップは DataStore をインスタンス化することです。これは、dataStore によって作成されたプロパティ デリゲートを使用して行います。これには、データが保存されるファイル名とシリアライザー クラス (上で定義した) を指定する必要があります。
private const val DATA_STORE_FILE_NAME = "todo.pb"
private val Context.todoItemDatastore: DataStore<TodoItems> by dataStore(
fileName = DATA_STORE_FILE_NAME,
serializer = TodoItemSerializer,
)
このコード部分は、選択したクラスの先頭、クラス自体の定義の上に存在する必要があります。つまり:
private const val DATA_STORE_FILE_NAME = "todo.pb"
private val Context.todoItemDatastore: DataStore<TodoItems> by dataStore(
fileName = DATA_STORE_FILE_NAME,
serializer = TodoItemSerializer,
)
class YourClassName {
}
アプリケーションの残りの部分でこのオブジェクトにアクセスするには、コンテキストを使用する必要があります。例は、ビューモデル クラスでアプリケーション コンテキストを使用することです。
class MyViewModel(application: Application): AndroidViewModel(application) {
val todoDataStore = application.todoItemDataStore
//...
}
Kotlin フローの使用方法
データストアに必要なすべての設定が完了したので、実際にデータストアと対話する方法について説明します。データを読み書きしたいと考えます。ただし、その方法は、皆さんがよく知っている SharedPreferences とは異なります。
上で定義したデータストアには、データストアで定義したプロパティのフローを公開するデータ フィールドがあります。
🚰 フローに慣れていない場合は、ここから始めると良いでしょう。
val todoItemFlow: Flow<TodoItems> = todoItemDataStore.data
.catch { exception ->
if (exception is IOException) {
emit(TodoItems.getDefaultInstance())
} else {
throw exception
}
}
上記のコードは、Proto DataStore からデータを収集するフローを定義する方法を示しています。例外が発生した場合に備えて catch ブロックが追加されました。このロジックを DataStore を定義したクラスに配置し、ビューモデル内で同様に使用できます。
val todoItemsFlow: LiveData<TodoItems> = todoItemsRepository.todoItemFlow.asLiveData()
Flow を LiveData に変換した方法に注目してください。これを行う理由は次の 2 つです。
<オル>これを行うには、次の依存関係を build.gradle ファイルに追加する必要があります。
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2"
アクティビティ/フラグメント クラスでは、このライブ データを次のように観察できます。
myViewModel.todoItemFlow.observe(LocalLifecycleOwner.current) { todoItems ->
// Logic to access data from DataStore
}
DataStore を使用する理由とタイミング
すべてを確認したら、部屋の中の象について話しましょう。既存のプロジェクトまたは次のプロジェクトで DataStore (Preferences または Proto) を使用する必要がありますか?
私の意見では、 答えははいであるはずです。 。 Google が SharedPreferences から移行しているという事実に加えて、DataStore はデータの永続化ではなくアプリケーションに集中できるようにする多くの利点を提供します。
UI スレッドから DataStore を操作するのは安全であり (作業が自動的に I/O に移動されるため)、フローを使用する必要があり (まだ使用していない場合)、その利点をすべて享受できます。 SharedPreferences から Preferences DataStore に簡単に移行するオプションもあります。
Proto DataStore の代わりに Room の使用を検討している場合、それはユースケースによって異なります。保存 (または永続化) するデータの量がかなり少なく、部分的な更新が必要ない場合は、Proto DataStore が適しています。より大規模なデータ セットまたは複雑なデータ セットがある場合は、代わりに Room の使用を選択する必要があります。
このコードすべてがアプリケーションでどのように表示されるかを確認したい場合は、ここで確認できます。
私が書いた他の記事を読みたい場合は、ここでご覧いただけます:
読んでいただきありがとうございます!
参考文献:
- プロトコル バッファのドキュメント (proto 3)
- Proto DataStore コードラボの使用
- データストアのドキュメント
無料でコーディングを学びましょう。 freeCodeCamp のオープンソース カリキュラムは、40,000 人以上の人々が開発者としての職に就くのに役立ちました。始めましょう
-
そのアーキテクチャのすべて:さまざまなアーキテクチャ パターンと、それらをアプリで使用する方法を調べる
Kriptofolio アプリ シリーズ - パート 3 新しいアプリの構築を開始する際に注目すべき最も重要なことは、アーキテクチャです。あなたが犯す可能性のある最大の間違いは、アーキテクチャ スタイルをまったく使用しないことです。 近年、アーキテクチャの選択に関するトピックは、Android コミュニティで非常に物議を醸しています。 Google も参加することを決めました。 2017 年には、Android アーキテクチャ コンポーネントをリリースすることで、標準化されたアーキテクチャの独自のアプローチを提案しました。開発者の生活を楽にすることを目的としていました. この投稿では、ま
-
初心者向けブロードキャストレシーバー
安定したインターネット接続に依存するアプリケーションがあるとします。インターネット接続が変更されたときにアプリケーションに通知を受け取る必要があります。どうやってそれをしますか?可能な解決策は、インターネット接続を常にチェックするサービスです。この実装はさまざまな理由で悪いので、考慮しません。この問題の解決策は Broadcast Receiver であり、指示された変更をリッスンします。ブロードキャスト レシーバーは、アプリケーションのステータスに関係なく、常にブロードキャストの通知を受け取ります。アプリケーションが現在実行されているか、バックグラウンドで実行されているか、まったく実行されて