这三个Rx可观察到的所有方法都按预期工作..哪种方式是最好的



我正在尝试以反应性的方式访问我的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是这里的最佳选择,因为它仅适合您的需求:执行一些代码并返回值。defercreate用于更复杂的情况,例如包装回调或操纵流的生命周期。

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周围的一个反应性包装器。

相关内容

最新更新