2017-12-28 24 views
0

を組み合わせる:のRx +レトロフィット+ルーム - 私は次のような問題を持っているシングルおよびフロアブル

私はレトロフィットを使用してシングル<>要求を取得し、フロアブル<>(ルーム)とそれを組み合わせる必要があります。両方が完了すると、UIにデータが表示されます。そして私はルームから継続的なアップデートを受けたいと思っています。

これは一般的な方法であるため、zip演算子を使用しようとしましたが、zipの問題は両方のソースからのデータを待つことです。つまり、 Retrofitから新鮮なデータも必要とするため、新しいエミッションを伝播します。

私の現在のソリューションは、combineLatestを使用して、このいずれかになります。

Flowable<UiModel> getData() { 
    return Flowable.combineLatest(networkService.getUsers().toFlowable(), 
      roomDao.getBooks(), UiModel::success) 
      .onErrorReturn(UiModel::error) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .startWith(UiModel.loading()); 
} 

これは動作しますが、マイナーな問題のカップルがあります。最初に、UiModelの複数の排出物があります。これはcombineLatestで期待されています。データベースからのデータを含む最初のモデルを取得し、ネットワーク要求が完了すると2番目のモデルを取得します。私はskip(1)演算子を使用して最初の発光をスキップすることができますが、ネットワークサービスをローカルキャッシュに置き換えようとしましたが、両方のデータソースが同じ(似たような)時間に終了すると、combineLatestは単一のUiModelを放出します。

私が欲しいものを達成するためのより良い方法はありますか?

EDIT:onErrorReturnの前に.distinctUntilChanged演算子を追加しました。それは実際にはどんな問題も解決するはずです。

+0

あなたは継続的な排出を望みますが、 'UiModel :: success'を呼びたくないのですか? –

答えて

1

Flowableを使用したルームとネットワーク通話を分割するとどうなりますか?あなたのビューが作成されたときに

は同時に

(そのデータを示すために、いくつかのタイムスタンプがキャッシュされたとの)データがある場合は、ユーザーにそれを表示することができ、部屋からキャッシュされたデータを取得するための要求を行いますネットワーク(これはバックグラウンドスレッドに留まることができます)と、ネットワークサービスが返されたデータをテーブルに挿入するようにします。データが異なる場合はエントリを更新し、Flowableは出力します。データが同じテーブルで更新されず、Flowableが発行されない場合に発生します。

スプリットの理由は、観測ストリームの制御が優れているため、変更が発生するたびに1回だけ放出され、もう1回放出されるからです。

関連する問題