98

LiveData クラスのこれら 2 つのメソッドの違いは何ですか? 公式ドキュメントとチュートリアルは、それについてかなり曖昧です。map()メソッドでは、最初のパラメータはsourceを呼び出しましたが、switchMap()ではtriggerを呼び出しました。その背後にある理論的根拠は何ですか?

4

13 に答える 13

24

上記の良い答えはすでにいくつかありますが、理解するまで苦労したので、技術的な詳細やコードには立ち入らずに、私の考え方で人々に具体的な例を説明しようと思います。

と の両方mapソース(またはトリガー) のライブ データがあり、どちらの場合も、それを別のライブ データに変換する必要があります。どちらを使用するかは、変換が実行しているタスクによって異なります。switchMap

map

どこでも使用されているのと同じ単純な例を考えてみましょう -ソースライブ データにはUserオブジェクトが含まれています -LiveData<User>は、現在ログインしているユーザーを指します。UI に というテキストを表示したいとしますCurrent user: <USERNAME>。この場合、ソースからの各変更シグナルは、結果の "マップされた" シグナルを 1 つだけトリガーする必要がありLiveDataます。たとえば、現在のUserオブジェクトが「Bob」の場合、UI テキストには が表示されますCurrent user: Bob。トリガーが変更をLiveData<User>トリガーすると、UI はそれを監視し、テキストを に更新しますCurrent user: Alice。非常に単純で、直線的で、1 対 1 の変化です。

switchMap

次の例を考えてみましょう。指定された検索語に名前が一致するユーザーを表示する UI を作成したいとします。これについては非常に賢く、検索語を LiveData として保持できます。したがってLiveData<String>、ユーザーが新しいクエリ文字列を入力するたびに、Fragment/Activityはテキスト入力値をこのライブ データに設定するだけViewModelです。その結果、このライブ データは変更信号を発生させます。このシグナルを受け取ったら、ユーザーの検索を開始します。ここで、検索が非常に高速であるため、すぐに値が返されると考えてみましょう。この時点で、あなたはただ使うことができると思いますmapUI を更新する一致するユーザーを返します。データベースを定期的に更新していて、次の更新後に検索用語に一致するユーザーがさらに表示されると想像してみてください。ご覧のように、このシナリオでは、ソース トリガー (検索語) がマップされたライブ データの単一のトリガーになるとは限りません。UI に指定されたマップされたライブ データは、新しいユーザーが追加された後も値をトリガーし続ける必要がある場合があります。データベース。この時点で、ソーストリガーを待つだけでなく、指定された用語に一致するユーザーのデータベースを監視する「よりスマートな」ライブデータを返すことができると言うかもしれません ( RoomDB outでそれを行うことができます)。箱の)。しかし、別の質問があります。検索用語が変わったらどうなるでしょうか。だからあなたの任期はx、ユーザーにクエリを実行してデータベースを監視するライブデータをトリガーし、返さuserx, userxxれ、5分後に返さuserx, userxxx​​れます。その後、用語は に変更されましたy。ここで、何らかの形でユーザーに提供するスマート ライブ データのリッスンを停止し、x監視してユーザーの名前に提供する新しいスマート ライブ データに切り替える必要があります。yそして、それはまさにswitchMapやっていることです!switchMap(...).observeそして、この切り替えは、UIで 1 回だけ記述するような方法で行う必要があることに注意してください。つまり、実行中は同じままでswitchMapあるラッパーを返す必要がありますが、内部ではライブ データ ソースを切り替える必要があります。我ら。LiveData

結論

一見同じように見えますが、 と のユース ケースmapswitchMap異なります。ケースの実装を開始すると、ほとんどの場合、マッピング関数でいくつかの関数を呼び出す必要があることに気付くと、どちらを使用するかがわかります。Repositoriesを返す他のモジュール ( など) からのコードLiveData

于 2020-02-08T01:12:20.693 に答える