我正在尝试以反应性的方式访问我的contentResolver。我知道存在Sqlbrite,但我必须使用SQLite。我是RXJAVA(2(的新手,并以某种方式将3个呼叫拼接在一起,所有这些电话都可以神奇地奏效。我不知道要使用哪一个。我正在使用rxjava2,而我读过的一些文章使我到了这一点。完成此操作的首选方法是什么?我也不使用retrolambda ...婴儿的步骤(我承认,虽然看起来确实很好(。
这是起始呼叫和订阅函数:
Observable<Cursor> dbObserver = mTmdbDatabaseService.getCursor1(123456);
dbObserver.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(testDBObserver());
private Observer<Cursor> testDBObserver() {
return new Observer<Cursor>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "testDBObserver.onSubscribe");
//Save the disposable to remove it later onDestroy
mCompositeDisposable.add(d);
}
@Override
public void onNext(Cursor c) {
int num = c.getCount();
Log.d(TAG, "testDBObserver.onNext: " + c.getCount());
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "testDBObserver.onError");
}
@Override
public void onComplete() {
Log.d(TAG, "testDBObserver.onComplete");
}
};
}
这是目前查询我的DB的三个RXJAVA函数:
public Observable getCursor1(final int value) {
Observable<Cursor> cursorObservable = Observable.fromCallable(new Callable<Cursor>() {
@Override
public Cursor call() throws Exception {
int id = value;
String stringId = Integer.toString(id);
Uri uri = MovieContract.MovieEntry.CONTENT_URI;
uri = uri.buildUpon().appendPath(stringId).build();
Cursor c = mContext.getContentResolver().query(uri,
null,
null,
null,
MovieContract.MovieEntry.COLUMN_MOVIE_ID);
return c;
}
});
return cursorObservable;
}
public Observable<Cursor> getCursor2(final int value) {
return Observable.defer(new Callable<ObservableSource<? extends Cursor>>() {
@Override
public ObservableSource<? extends Cursor> call() throws Exception {
int id = value;
String stringId = Integer.toString(id);
Uri uri = MovieContract.MovieEntry.CONTENT_URI;
uri = uri.buildUpon().appendPath(stringId).build();
Cursor c = mContext.getContentResolver().query(uri,
null,
null,
null,
MovieContract.MovieEntry.COLUMN_MOVIE_ID);
return Observable.just(c);
}
});
}
public Observable<Cursor> getCursor3(final int value) {
Observable<Cursor> observable = Observable.create(new ObservableOnSubscribe<Cursor>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Cursor> subscriber) throws Exception {
int id = value;
String stringId = Integer.toString(id);
Uri uri = MovieContract.MovieEntry.CONTENT_URI;
uri = uri.buildUpon().appendPath(stringId).build();
Cursor c = mContext.getContentResolver().query(uri,
null,
null,
null,
MovieContract.MovieEntry.COLUMN_MOVIE_ID);
subscriber.onNext(c);
subscriber.onComplete();
}
});
return observable;
}
Observable.fromCallable
是这里的最佳选择,因为它仅适合您的需求:执行一些代码并返回值。defer
和create
用于更复杂的情况,例如包装回调或操纵流的生命周期。
TIP :由于您使用的是Cursor
,我认为更好的设计解决方案是从数据源(而不是光标本身(发出精确的数据,并关闭位于现场的光标:
Observable<Result> cursorObservable = Observable.fromCallable ... {
@Override
public Cursor call() throws Exception {
...
Cursor c = ...
Result result = ... //get your data from the cursor
c.close();
return result;
}
});
P.S。Sqlbrite只是Sqlite周围的一个反应性包装器。