这三个 RX observables 都按预期工作......哪种方式最好?

These three RX observables all work as expected...which way is the best?

我正在尝试调用我的 contentResolver,它以反应方式访问我的 sql 数据库。我知道 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");
        }
    };
}

这些是现在查询我的数据库的三个 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 是这里的最佳选择,因为它正好符合您的需要:执行一些代码并 return 一个值。 defercreate 适用于更复杂的情况,例如包装回调或操纵流的生命周期。

提示:由于您使用的是 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 的反应式包装器。