私のAndroidプロジェクトでは、RxJava2,SqlBrite(RxJavaInteropを使用)とSqlDelightを大いに頼りにしています。他の件名にRxJava2 Dbを照会してください
無期限に(サービスが停止するまで)行く予定の1つのrxストリームがあり、その上に.flatMap
のFunction<String, ObservableSource<Action>>
があります。
意味では、このflatMap
はSubject<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は永遠にハングします。
そこで質問:
私はそれをどのように行うことができますか?
リレーが良いアイデアだと私はそれを確認します。しかし、残念ながら0または1はあなたの提案では解決しません。 RxJava2は 'null'を受け付けず、直接NPEを投げます。また、観測可能なDB要求は、sqlbriteライブラリによって作成されます。ですから、私はその1回限りのイベントだけを必要とし、それをシャットダウンするためにタイムアウトを処理したり、タイムアウトしたりする必要があります。次に新しいクエリーになる次の 'actionId'を待ちます。あなたに努力してくれてありがとう。 – Budius
ヌルを送ることができないので、私はアイテムとかその不在をクラスに入れるための基本モナドを書くことを考えていました。それから、Observableの代替手段としてすでに存在している可能性があると思いました。それはちょうど完璧なフィットだから、私は私の答えを更新しました。 –