AndroidでRxJavaを使用する場合と、Android Architectural ComponentsのLiveDataを使用する場合


186

AndroidでRxJavaを使用し、Android Architectural ComponentsからLiveDataを使用する理由がわかりません。両方のユースケースと違いを、サンプルの例と一緒に、両方の違いを説明するコードの形式で説明すると、非常に役立ちます。


6
良い理由はもう見つかりましたか?私は同じことを思っています...
IgorGanapolsky

回答:


117

Android LiveDataは元のオブザーバーパターンの変形で、アクティブ/非アクティブの遷移が追加されています。そのため、その範囲は非常に制限されています。

Android LiveDataで説明されている例を使用して、位置データを監視し、アプリケーションの状態に基づいて登録および登録解除するクラスが作成されます。

RxJavaは、より一般化された演算子を提供します。このオブザーバブルが位置データを提供すると仮定しましょう:

Observable<LocationData> locationObservable;

オブザーバブルの実装は、以下を使用して構築できます。 Observable.create()コールバック操作のマッピングにして。オブザーバブルがサブスクライブされるとコールバックが登録され、サブスクライブが解除されるとコールバックが登録解除されます。実装は、例で提供されているコードと非常によく似ています。

また、アプリケーションがアクティブなときにtrueを放出するオブザーバブルがあると仮定します。

Observable<Boolean> isActive;

次に、以下によってLiveDataのすべての機能を提供できます。

Observable<LocationData> liveLocation =
  isActive
    .switchMap( active -> active ? locationObservable : Observable.never() );

switchMap()アプリケーションがアクティブでない場合、オペレータは、いずれかのストリーム、または何として現在の場所を提供します。あなたが持ってたらliveLocation、観察を、そこにあなたがRxJava演算子を使用してそれを行うことができますがたくさん。私のお気に入りの例は:

liveLocation.distinctUntilChanged()
  .filter( location -> isLocationInAreaOfInterest( location ) )
  .subscribe( location -> doSomethingWithNewLocation( location ) );

これは、場所が変更されたときにのみアクションを実行し、場所は興味深いものになります。時間演算子を組み合わせて速度を決定する同様の操作を作成できます。さらに重要なことは、RxJavaオペレーターを使用して、操作がメインスレッドで発生するか、バックグラウンドスレッドで発生するか、複数のスレッドで発生するかを詳細に制御できることです。

RxJavaのポイントは、ライブラリから提供されるオペレーション、またはユーザーが提供するカスタムオペレーションを使用して、制御とタイミングを単一のユニバースに結合することです。

LiveDataは、そのユニバースの1つの小さな部分のみを扱いますliveLocation


2
おかげで、LiveDataドキュメントはロケーションサンプルを参照しなくなったようです。ここにはもっと興味深いポイントがあります(場所のサンプル付き):androidkt.com/livedata
Daniel Wilson

5
@DanielWilsonリンクはもう利用できません。
Tura

私はwtfがそのリンク上にいたのを思い出せません:ライブデータ用のMark AllisonのサンプルコードのようなDI:blog.stylingandroid.com/architecture-components-livedata
Daniel Wilson

3
The point of RxJava is that it combines control and timing into a single universe, using operations provided from the library, or even custom operations that you provide. ただし、LiveDataライフサイクルは認識されません。Rxを使用する場合、ライフサイクルの変更を処理する必要はありませんか?
Sparker0i

@ Sparker0iはここでポイントを得ました。RxJavaはライフサイクルを認識しません。手動で処理する必要があります。LiveDataと同様に、ライフサイクルはすでに処理されています。
Aks4125 2018

119

元の質問に関しては、RxJavaとLiveDataの両方が非常によく補完し合っています。

LiveDataAndroidのライフサイクルやとの緊密な統合により、ViewModelレイヤーを際立たせていますViewModelRxJava変換でより多くの機能を提供します(@Bob Dalgleishが言及)。

現在、RxJavaデータソースレイヤーとリポジトリレイヤーでLiveData使用してLiveDataReactiveStreamsおり、(アクティビティ/フラグメントにデータを公開する前に)ViewModelで(を使用して)に変換されます。このアプローチに非常に満足しています。


8
私たちがあなたを正しく理解していれば、LiveDataはAndroid UI固有の実装でのみ役立ちます。Clean Architectureを使用して汎用アプリを作成し、このアーキテクチャを他のプラットフォームと共有している場合、RxJavaはLiveDataよりも適していますか?
IgorGanapolsky

@IgorGanapolsky一般的なアプリでどの言語/フレームワークを使用していますか?
kzotin

Java / Kotlinで記述されたAndroidに依存しないAPIとClean Arch。
IgorGanapolsky

1
あなたの答えでLiveDataReactiveStreamsの実際の例を提案できますか?
パワン

2
あなたがそれを必要としない@kzotin observeOnLiveDataReactiveStreams呼び出すことによって、そのとにかくを行いますLiveData.postValue()。またsubscribeOn、一般的に効果があるという保証はありません。
arekolek

77

LiveDataとRxJavaの間には多くの違いがあります。

  1. LiveDataはSTREAMではありませんが、RxJavaではすべて(文字通りすべて)がSTREAMです。
  2. LiveDataは、監視可能なデータホルダークラスです。通常のオブザーバブルとは異なり、LiveDataはライフサイクルを認識します。つまり、アクティビティ、フラグメント、サービスなど、他のアプリコンポーネントのライフサイクルを尊重します。この認識により、LiveDataは、アクティブなライフサイクル状態にあるアプリコンポーネントオブザーバーのみを更新します。
  3. LiveDataは同期型であるため、RxJavaの場合のようにLiveDataだけを使用してコードのチャンク(ネットワーク呼び出し、データベース操作など)を非同期で実行することはできません。
  4. このデュオを最大限に活用するためにできる最善のことは、ビジネスロジック(ネットワーク呼び出し、データ操作など、リポジトリ内外で発生するすべてのもの)にRxJavaを使用することです。)に使用し、プレゼンテーション層にLiveDataを使用するのが最善です。これにより、ビジネスロジックの変換機能とストリーム機能、およびUIのライフサイクル対応操作を取得できます。
  5. LiveDataとRxJavaは、一緒に使用すると互いに補完します。つまり、RxJavaですべてを行い、最後にUIを更新したいときに、以下のコードのようなことを実行して、ObservableをLiveDataに変更します。したがって、ビュー(UI)はViewModelのLiveDataを監視し、LiveDataは変更不可能なMutableLiveData(またはMutableLiveDataは変更可能なLiveData)にすぎません。
  6. では、ここで問題は、なぜ最初からLiveDataを使用する必要があるのか​​、ということです。 以下のコードを見るとわかるように、RxJavaからの応答をMutableLiveData(またはLiveData)に保存し、LiveDataはライフサイクルを認識しているため、データはライフサイクルを認識しています。ここで、UIを更新するタイミングとタイミングをデータ自体が知っている場合の可能性を想像してください。
  7. LiveDataには履歴がありません(現在の状態のみ)。したがって、チャットアプリケーションにはLiveDataを使用しないでください。
  8. RxJavaでLiveDataを使用する場合、MediatorLiveDataSwitchMapなどのようなものは必要ありません。これらはストリーム制御ツールであり、RxJavaはその点で優れています。
  9. LiveDataをデータホルダーとして、それ以外のものと見なしてください。また、LiveDataはライフサイクル対応の消費者であるとも言えます。

    public class RegistrationViewModel extends ViewModel {
        Disposable disposable;

        private RegistrationRepo registrationRepo;
        private MutableLiveData<RegistrationResponse> modelMutableLiveData =
                new MutableLiveData<>();

        public RegistrationViewModel() {
        }

        public RegistrationViewModel(RegistrationRepo registrationRepo) {
            this.registrationRepo = registrationRepo;
        }

        public void init(RegistrationModel registrationModel) {
            disposable = registrationRepo.loginForUser(registrationModel)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Response<RegistrationResponse>>() {
                        @Override
                        public void accept(Response<RegistrationResponse>
                                                   registrationModelResponse) throws Exception {

                            modelMutableLiveData.setValue(registrationModelResponse.body());
                        }
                    });
        }

        public LiveData<RegistrationResponse> getModelLiveData() {
            return modelMutableLiveData;
        }

       @Override
       protected void onCleared() {
                super.onCleared();
            disposable.dispose();
         }
    }

5
LiveDataをデータホルダーとして、それ以外のものと見なしてください。==>はい
Lou Morda

3
いい例です。使い捨てを宣言するのを忘れたので、でそれらをクリアするとよいでしょうonCleared
Snicolas

livedataがどのように同期しているか説明していただけますか?私の知る限り、Livedataオブジェクトを別のスレッドに送信し、そのスレッドが値をポストすることができます。
Hitesh Bisht

私が書いたものをもう一度読んだ場合は、RxJavaを使用してできるのと同じように、LiveDataを使用して別のスレッドで作業することはできません(はい、私はそこだけでも使用しました)
Abhishek Kumar

ライフサイクルはLiveDataの大きな差別化要素ではありませんか?1.パイプラインが何をする必要があるか、最終結果は何かを説明します。2。「observe」句で結果をサブスクライブします。3。パイプラインは、ライフサイクルの状態で許可されている場合にのみ操作されます。
Srg

29

実際、LiveData はと本質的に異なるツールではないRxJavaので、RxJavaオブザーバブルのすべてのサブスクリプションをCompositeDispoable オブジェクトに格納してonDestroy() から、Activity またはonDestroyView()Fragment 1つだけを使用してそれらを破棄することにより、ライフサイクルを簡単に管理できる アーキテクチャコンポーネントとして導入されたのはなぜですか。コードの行?

私は一度RxJavaを使用して映画検索アプリを作成し、次にLiveDataを使用してこの質問に完全に回答しまし

しかし、要するに、そうすることはできますが、そのためには、基本的なライフサイクルの知識を持つ以外に、まず関連するライフサイクルメソッドをオーバーライドする必要があります。これはまだ一部の人には意味をなさないかもしれませんが、実際には、Google I / O 2018のJetpackセッションの 1つによると、多くの開発者がライフサイクル管理が複雑であることを発見しています。ライフサイクルの依存関係を処理しないことに起因するクラッシュエラーは、一部の開発者が、ライフサイクルを知っていても、アプリで使用するすべてのアクティビティ/フラグメントでその処理を忘れていることを示す別の兆候である可能性があります。大規模なアプリでは、生産性に悪影響を及ぼす可能性があるにもかかわらず、これが問題になる可能性があります。

つまり、を導入LiveDataすることで、ライフサイクル管理、メモリリーク、クラッシュを理解しなくても、より多くの開発者がMVVMを採用することが期待されます。機能と開発者に与える力の点でLiveData比較できないことは間違いありませんRxJavaが、反応型プログラミングRxJavaは多くの人にとって理解しにくい概念とツールです。反対に、私は多くの開発者が経験している論争の的になっている広範囲にわたる問題を処理するための非常にシンプルなツールであるとLiveDataは思いませんRxJava

**更新** ここに、LiveDataの誤用が予期しない結果につながる可能性があることを説明した新しい記事を追加しました。RxJavaはこれらの状況で救助に来ることができます



2
「RxJavaがすべてのサブスクリプションをCompositeDispoableに保存し、アクティビティのonDestroy()で破棄することにより、ライフサイクルを簡単に管理できるようになったのはなぜですか」- 実際にはLiveDataonStop
破棄さ

私の理解による@arekolek:CompositeDispoableを処理する場合でも、ライフサイクルメソッドが上書きされます。ただし、ライブデータでは、すべてが1行のコードに含まれます。したがって、最低20行のコードを節約できます。
Suresh、

baseFragmentを定義し、すべての派生フラグメントによってオーバーライドされるDisposable [] subscriptions()メソッドを定義して、このメソッドをonCreateViewで呼び出し、戻り値をCompositeDisposableに追加し、onDestroyViewで破棄することで、忘れることはありません。
android2013

それは処分だけではありません。RxJavaを使用して、onStopで破棄し、onStart / onResumeで再度サブスクライブし、構成変更を処理し、その他の一連の処理を行う必要があります。そのため、RxJavaを使用すると非常に多くのクラッシュが発生します。LiveDataはこれらすべてを処理しますが、RxJavaほど柔軟ではありません。
user932178

24

リアクティブエコシステムでは、データを放出するObservableと、このObservable放出をサブスクライブ(通知)するObserverがあることを知っているかもしれませんが、いわゆるObserverパターンがどのように機能するかは奇妙なことではありません。オブザーバブルは何かを「叫び」、オブザーバーは与えられた瞬間にオブザーバブルが何かを叫ぶことを通知されます。

状態LiveDataにあるオブザーバーを管理できるオブザーバブルと考えてくださいactive。つまりLiveData、単純なObservableです、ライフサイクルも処理します。

しかし、リクエストした2つのコードケースを見てみましょう。

A)ライブデータ

B)RXJava

A)これはLiveDataの基本的な実装です

1)通常、ViewModelでLiveDataをインスタンス化して、向きの変更を維持します(読み取り専用のLiveData、または書き込み可能なMutableLiveDataを使用できるため、通常はクラスLiveDataから外部に公開します)。

2)メインアクティビティのOnCreateメソッド(ViewModelではない)で、Observerオブジェクト(通常は、onChangedメソッド)を「サブスクライブ」します。

3)リンクを確立するためにメソッドObserveを起動します

まずViewModel(ビジネスロジックを所有)

class ViewModel : ViewModel() { //Point 1

    var liveData: MutableLiveData<Int> = MutableLiveData()

}

そしてこれはMainActivity(可能な限り馬鹿な)

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val ViewModelProvider= ViewModelProviders.of(this).get(ViewModel::class.java)

        ViewModelProvider.observe(this, Observer {//Points 2 and 3
            //what you want to observe
        })


        }
    }
}

B)これはRXJavaの基本的な実装です

1)オブザーバブルを宣言する

2)オブザーバーを宣言する

3)オブザーバーでオブザーバブルをサブスクライブします

Observable.just(1, 2, 3, 4, 5, 6) // Point 1

   .subscribe(new Subscriber() {    //Points 2 & 3
       @Override
       public void onCompleted() {
           System.out.println("Complete!");
       }

       @Override
       public void onError(Throwable e) {
       }

       @Override
       public void onNext(Double value) {
           System.out.println("onNext: " + value);
       }
    });

特に、(これまで見てきたように)アーキテクチャコンポーネントと共にLiveData使用されLifecycle、しばしば使用されViewModelます。実際LiveData、をViewModelと組み合わせると、オブザーバーのすべての変更をリアルタイムで更新し続けることができるため、イベントは必要な場所でリアルタイムに管理されます。ライフサイクルLiveDataの概念と関連オブジェクトLifeCycleOwner / LifeCycleを理解するために使用することを強くお勧めします。また、実際のシナリオで実装する場合は、変換を確認することをお勧めします。ここでは、優れたコモンズウェアからいくつかのユースケースを見つけることができます。LiveData

まとめると、基本的にLiveDataは簡略化さRXJavaれた、コンポーネント間に明示的ないわゆる依存関係ルールを作成せずに複数のコンポーネントにわたる変更を監視するための洗練された方法です。これにより、コードのテストが容易になり、コードが読みやすくなります。RXJavaを使用すると、LiveDataなどの機能を実行できます。RXJavaの拡張機能により、単純な場合にLiveDataを使用することも、RXJavaのすべての機能を活用してAndroidアーキテクチャコンポーネントを ViewModelとして使用し続けることもRXJavaできます。もちろん、これははるかに複雑になる可能性があるため、代わりに何百もの演算子があると考えてください。 SwitchMapのマップとLiveDataのマップ(現時点)。

RXJavaバージョン2は、オブジェクト指向のパラダイムに革命をもたらし、プログラムのフローを管理するいわゆる機能的な方法を追加したライブラリです。


4

LiveDataは、Androidチームによって開発されたAndroidアーキテクチャコンポーネントのサブセットです。

ライブデータやその他のアーキテクチャコンポーネントを使用すると、メモリリークやその他の同様の問題がアーキテクチャコンポーネントによって処理されます。androidチームが開発しているため、androidに最適です。また、Androidの新しいバージョンを処理するアップデートも提供しています。

Androidアプリ開発でのみ使用する場合は、Androidアーキテクチャコンポーネントを使用してください。それ以外の場合、他のJavaアプリ(ウェブアプリ、デスクトップアプリなど)を使用する場合は、RxJavaを使用します。


私はあなたの答えを明確にしようとしました。何らかの形で元の意図と矛盾した場合は、自由に編集してください。その場合は、最初のリビジョンよりも明確にするようにしてください。正直なところ、回答の最後の部分は意味がありませんでした。
ゾーイ

2

LiveDataデータ保持者のものとして、他には何もありません。また、LiveDataはライフサイクル対応の消費者であるとも言えます。LiveDataライフサイクルの概念と関連オブジェクトLifeCycleOwner / LifeCycleを理解しておくことを強くお勧めします。これにより、ビジネスロジックの変換機能とストリーム機能、およびUIのライフサイクル対応操作を利用できます。

Rxは、エレガントな宣言型スタイルで問題を解決できる強力なツールです。ビジネス側のオプションまたはService API操作を処理します


0

LiveDataとRxJavaを比較すると、リンゴとフルーツサラダが比較されます。

LiveDataとContentObserverを比較して、リンゴとリンゴを比較します。LiveDataは、事実上、ContentObserverのライフサイクル対応の代替品です。

RxJavaをAsyncTaskまたは他のスレッドツールと比較すると、RxJavaはスレッドだけではなく、フルーツサラダとオレンジを比較できます。


0
  • LiveDataはRx SubjectまたはSharedRxObservableと部分的に等しい

  • LiveDataはサブスクリプションのライフサイクルを管理しますが、Rxサブジェクトサブスクリプションは手動で作成および破棄する必要があります

  • LiveDataには終了状態はありませんが、RxサブジェクトにはOnErrorおよびOnCompletedがあります

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.