をカプセル化して、ContentProvider
を照会し、ContentProvider
カーソルをサブスクライブして継続的な更新を提供するロジックをカプセル化したいとします。RxJavaに必要なルーパースレッドを管理する方法
私は観察可能なので、私はそれをSchedulers.io()
で購読する必要があります。その問題は、ContentObserver
を登録することができないということです。なぜなら、ルーパーの準備スレッドが必要だからです。
これを管理するにはどうすればよいでしょうか。はを1つのObservable
でカプセル化しています。
あることを示すために、コード:
public Observable<Integer> unreadCountObservable() {
return Observable.create(subscriber -> {
new UnreadCountObservable(subscriber);
});
}
private class UnreadCountObservable {
private Subscriber subscriber;
public UnreadCountObservable(Subscriber subscriber) {
this.subscriber = subscriber;
Cursor cursor = queryUnread(subscriber);
cursor.registerContentObserver(observer);
subscriber.add(Subscriptions.create(() -> {
cursor.unregisterContentObserver(observer);
cursor.close();
}));
}
@NonNull
private Cursor queryUnread(Subscriber subscriber) {
Cursor cursor = contextProvider.getContext().getContentResolver().query(Uri.parse(CONTENT_URI),SMS_PROJECTION,SMS_SELECTION_UNREAD,SMS_PROJECTION,null);
if(cursor.moveToNext()) {
Integer count = cursor.getInt(0);
subscriber.onNext(count);
} else {
subscriber.onNext(0);
}
return cursor;
}
private ContentObserver observer = new ContentObserver(new Handler()) {
@Override
public boolean deliverSelfNotifications() {
return false;
}
@Override
public void onChange(boolean selfChange) {
Timber.d("New sms data changed");
queryUnread(subscriber);
}
};
}
注1上記のコードの問題は、それが原因registerObserverに.subscribeOn(Schedulers.io()
で呼び出すことができない、それはそれは、その後のクエリをmainThreadと呼ばれていた場合ということです単一Observable
中のすべてをカプセル化重要な要件と、この質問
注)その上で実行
ここで、Observableを使用するアクティビティのHandlerThreadを作成し、そのスレッドからルーパーを使用することをお勧めします。しかし、より良い選択肢があるかどうか、また一般的なスケジューラ(例えばlooperIoScheduler())を作成することが問題を引き起こす可能性があるかどうかを知りたい
これは機能しません。 SubscribeOnはサブスクリプションチェーンに入りますが、チェーンの最初の文か最後の文かは関係ありません。そうすれば、ioスレッドの実行を延期し、UnreadCountObservableコンストラクターを実行することもできます。 – lujop