2017-02-16 9 views
0

私のAndroidプロジェクトでは、RxJava2,SqlBrite(RxJavaInteropを使用)とSqlDelightを大いに頼りにしています。他の件名にRxJava2 Dbを照会してください

無期限に(サービスが停止するまで)行く予定の1つのrxストリームがあり、その上に.flatMapFunction<String, ObservableSource<Action>>があります。

意味では、このflatMapSubject<Action>が含まれ、String actionIdを受け取り、それらたActionの一部(質問には無関係)処理を行い、条件に応じてActionオブジェクトをデータベースに照会し、subject

にそれを派遣する必要があります

私の最初のアプローチは、直接クエリを実行することでした。

Cursor c = db.query(...); 
if(c.moveFirst()) { 
    Action a = Action.SELECT_ALL_MAPPER.map(c); 
    subject.onNext(selectAll); 
} 

しかし、このブロック実行中のスレッドを、私はむしろ、次の操作を行う必要があり、独自のストリームでこれをトリガー:

  • クエリ(0または1つのアイテムを返すべき)
  • 値がある場合:Actionオブジェクトにマップとは値がない場合subject
  • に値をプッシュ:終了/処分が。
  • subjectは終了またはエラーを受信できません。それは将来の出来事のために生き続ける必要があります。

私の現在のアプローチは、次のコードです:

RxJavaInterop.toV2Observable(db.createQuery(
    Action.TABLE_NAME, 
    Action.FACTORY.Select_by_id(actionId).statement) 
    .mapToOne(new Func1<Cursor, Action>() { 
     @Override public Action call(Cursor cursor) { 
      return Action.SELECT_ALL_MAPPER.map(cursor); 
     } 
    })) 
    .take(1) 
    .subscribe(new Consumer<Action>() { 
     @Override public void accept(Action action) throws Exception { 
      subject.onNext(action); 
     } 
    }); 

そして、これが第一印象でトリックを行うようだが、私はそれにいくつかのエラーを参照してください。

  • 私がすることができますそれを処分しないでください。 Disposableオブジェクトへの参照を取得しても、Consumer<Action>から呼び出すことはできません。なぜなら、「初期化されていない可能性があります」(理由はわかっていますが、それは問題ありません)。
  • 与えられたIDを持つアクションがない場合、VMが強制終了されるまで、Observableは永遠にハングします。

そこで質問:

私はそれをどのように行うことができますか?

答えて

1

私はむしろRxAndroidを見てみましょう独自のストリーム

でこれをトリガします。 subjectが終了またはエラーを受け取ることができません

yourRxStream 
    .flatMap(*db request here*) 
    .subscribeOn(Schedulers.io()) 
    .subcribe(subject); 

:これは、ようになります。それは将来のイベントのために生き続ける必要があります 。

スイッチRelayと件名:

被験者は、非RxのAPIの間のギャップを埋めるために有用です。ただし、 は、ステートフルな状態にあります。onComplete またはonErrorを受け取ったとき、データの移動には使用できなくなります。これは の観測可能な契約であり、時には望ましい動作です。ほとんど 回ありません。

リレーは、前述の特性のない被験者です。彼らは を使って、非Rx APIをRxに簡単に橋渡しすることができます。また、誤って端末の状態が発生する心配もありません。


最後可能性出力0または1項目以上の要求に対して、Maybeを使用します。

+0

リレーが良いアイデアだと私はそれを確認します。しかし、残念ながら0または1はあなたの提案では解決しません。 RxJava2は 'null'を受け付けず、直接NPEを投げます。また、観測可能なDB要求は、sqlbriteライブラリによって作成されます。ですから、私はその1回限りのイベントだけを必要とし、それをシャットダウンするためにタイムアウトを処理したり、タイムアウトしたりする必要があります。次に新しいクエリーになる次の 'actionId'を待ちます。あなたに努力してくれてありがとう。 – Budius

+0

ヌルを送ることができないので、私はアイテムとかその不在をクラスに入れるための基本モナドを書くことを考えていました。それから、Observableの代替手段としてすでに存在している可能性があると思いました。それはちょうど完璧なフィットだから、私は私の答えを更新しました。 –

関連する問題