AndroidアプリでRxJavaを使用しており、データベースからデータをロードしたい。
このように、EventLog
のリストを返すObservable.create()
を使用して新しいObservableを作成しています
_public Observable<List<EventLog>> loadEventLogs() {
return Observable.create(new Observable.OnSubscribe<List<EventLog>>() {
@Override
public void call(Subscriber<? super List<EventLog>> subscriber) {
List<DBEventLog> logs = new Select().from(DBEventLog.class).execute();
List<EventLog> eventLogs = new ArrayList<>(logs.size());
for (int i = 0; i < logs.size(); i++) {
eventLogs.add(new EventLog(logs.get(i)));
}
subscriber.onNext(eventLogs);
}
});
}
_
正しく動作しますが、Observable.create()
を使用することは、Rx Java( ここ を参照)の場合、実際にはベストプラクティスではありません。).
この方法でこの方法を変更しました。
_public Observable<List<EventLog>> loadEventLogs() {
return Observable.fromCallable(new Func0<List<EventLog>>() {
@Override
public List<EventLog> call() {
List<DBEventLog> logs = new Select().from(DBEventLog.class).execute();
List<EventLog> eventLogs = new ArrayList<>(logs.size());
for (int i = 0; i < logs.size(); i++) {
eventLogs.add(new EventLog(logs.get(i)));
}
return eventLogs;
}
});
}
_
これはRx Javaを使用したより良いアプローチですか?どうして? 2つの方法の実際の違いは何ですか?
さらに、データベースは要素のリストをロードするため、リスト全体を一度に出力するのは理にかなっていますか?または、一度に1つのアイテムを放出する必要がありますか?
2つの方法は同じように見え、同じように動作しますが、fromCallable
はバックプレッシャーの問題を扱いますが、create
バージョンはそうではありません。 OnSubscribe
実装内のバックプレッシャーへの対処は、単純なものから完全に心を溶かすものまでさまざまです。ただし、省略した場合、非同期境界(MissingBackpressureException
など)または継続境界(observeOn
など)に沿ってconcat
sを取得できます。
RxJavaは、できるだけ多くのファクトリとオペレーターに適切なバックプレッシャーサポートを提供しようとしますが、それをサポートできないファクトリーとオペレーターはかなり多くあります。
手動でのOnSubscribe
実装の2番目の問題は、特にonNext
呼び出しを大量に生成する場合のキャンセルサポートの欠如です。これらの多くは、標準のファクトリメソッド(from
など)またはヘルパークラス(SyncOnSubscribe
など)で置き換えることができ、複雑さをすべて処理できます。
2つの理由で(まだ)create
を使用する多くの紹介と例を見つけるかもしれません。
create
に比例して時間をかけすぎています。2番目の質問、つまり、リストまたは一連の値を作成する必要があるかどうかは、ソースによって異なります。ソースが何らかの種類の反復または個々のデータ要素(JDBCなど)のストリーミングをサポートしている場合は、ソースにフックして1つずつ出力することができます(SyncOnSubscribe
を参照)。それがサポートされていないか、とにかくリスト形式で必要な場合は、そのままにしてください。必要に応じて、toList
およびflatMapIterable
を介して2つの形式間でいつでも変換できます。
応答 で説明したように、リンクしたObservable.create
を使用すると、RxJavaの高度な要件に違反する必要がある場合があります。
たとえば、 backpressure を実装するか、サブスクライブを解除する方法が必要です。
あなたの場合、バックプレッシャーやサブスクリプションに対処する必要なく、アイテムを発行したいとします。したがって、Observable.fromCallable
は適切な呼び出しです。 RxJavaが残りを処理します。