Realm 领域+;改装+;RxJava:Concat和SubscribeOn

Realm 领域+;改装+;RxJava:Concat和SubscribeOn,realm,retrofit,rx-java,concat,Realm,Retrofit,Rx Java,Concat,我在使用RxJava concat运算符时遇到问题。我有两个可观察对象,第一个从服务器数据库发出结果,另一个从本地数据库发出结果,然后我观察: // Uses a Realm in the UI thread Observable<MyResult> remoteObservable = mRemoteDataSource.find(tId); // Uses Retrofit Observable<MyResult> localObservable = mLocalD

我在使用RxJava concat运算符时遇到问题。我有两个可观察对象,第一个从服务器数据库发出结果,另一个从本地数据库发出结果,然后我观察:

// Uses a Realm in the UI thread
Observable<MyResult> remoteObservable = mRemoteDataSource.find(tId);

// Uses Retrofit
Observable<MyResult> localObservable = mLocalDataSource.find(tId);

Observable.concat(localObservable, remoteObservable)
    .doOnNext(result -> /* Do my stuff */)
    .observeOn(AndroidSchedulers.mainThread())
    .doOnError(throwable -> throwable.printStackTrace())
    .subscribe()
//在UI线程中使用域
Observable remoteObservable=mRemoteDataSource.find(tId);
//使用改装
Observable localObservable=mLocalDataSource.find(tId);
concat(localObservable,remoteObservable)
.doOnNext(结果->/*做我的事*/)
.observeOn(AndroidSchedulers.mainThread())
.doError(throwable->throwable.printStackTrace())
.subscribe()
因此,这导致了我的问题,因为我没有使用
subscribeOn()
连接的可观察对象正在
AndroidScheduler.MainThread()
上运行,而这不会运行远程,它会启动
networkMainThreadException

如果我实现一个
subscribeOn(Schedulers.computation())
我从错误的线程获得
领域访问权。领域对象只能在创建它们的线程上访问
,因为领域实例确实存在的线程上当然没有运行Observable

我搜索了其他问题,但没有得到任何有用的东西,我检查了realm制作的示例:但奇怪的是,我发现改进observable没有订阅任何内容,而且它是有效的


为什么它对示例有效,而在我的代码中我不能这样做?有什么建议吗?

我认为您应该在正确的位置使用
subscribeOn()

// Uses a Realm in the UI thread
Observable<MyResult> realmObservable = mRealmDataSource.find(tId).subscribeOn(AndroidSchedulers.mainThread());

// Uses Retrofit
Observable<MyResult> retrofitObservable = mRetrofitDataSource.find(tId).subscribeOn(Subscribers.io());

Observable.concat(realmObservable, retrofitObservable)
    .doOnNext(result -> /* Do my stuff */)
    .subscribeOn(AndroidSchedulers.mainThread())
    .observeOn(AndroidSchedulers.mainThread())
    .doOnError(throwable -> throwable.printStackTrace())
    .subscribe()
//在UI线程中使用域
Observable realmObservable=mRealmDataSource.find(tId).subscribeOn(AndroidSchedulers.mainThread());
//使用改装
Observable=mRetrofitDataSource.find(tId).subscribeOn(Subscribers.io());
concat(realmObservable,可观察)
.doOnNext(结果->/*做我的事*/)
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.doError(throwable->throwable.printStackTrace())
.subscribe()

查看它是否解决了您的问题。

您可以查看您的本地和远程观测值,如下所示:

// Uses a Realm in the UI thread
Observable<MyResult> remoteObservable = mRemoteDataSource.find(tId);

// Uses Retrofit
Observable<MyResult> localObservable = mLocalDataSource.find(tId);

Observable.concat(localObservable, remoteObservable).first()
                .map(new Func1<MyResult, MyResult>() {
                    @Override
                    public myResult call(MyResult result) {
                        if (result == null) {
                            throw new IllegalArgumentException();
                        }
                        return result;
                    }
                });
CompositeSubscription mCompositeSubscription = new CompositeSubscription();
final Subscription subscription = mRepo.find(tId
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<MyResult>() {
                    @Override
                    public void onCompleted() {
                        // Completed
                    }

                    @Override
                    public void onError(Throwable e) {
                        // onError
                    }

                    @Override
                    public void onNext(MyResult result) {
                        //onSuccess
                    }
                });
mCompositeSubscription.add(subscription);
//在UI线程中使用域
Observable remoteObservable=mRemoteDataSource.find(tId);
//使用改装
Observable localObservable=mLocalDataSource.find(tId);
concat(localObservable,remoteObservable).first()
.map(新函数1(){
@凌驾
公共myResult调用(myResult){
如果(结果==null){
抛出新的IllegalArgumentException();
}
返回结果;
}
});
并按以下方式订阅:

// Uses a Realm in the UI thread
Observable<MyResult> remoteObservable = mRemoteDataSource.find(tId);

// Uses Retrofit
Observable<MyResult> localObservable = mLocalDataSource.find(tId);

Observable.concat(localObservable, remoteObservable).first()
                .map(new Func1<MyResult, MyResult>() {
                    @Override
                    public myResult call(MyResult result) {
                        if (result == null) {
                            throw new IllegalArgumentException();
                        }
                        return result;
                    }
                });
CompositeSubscription mCompositeSubscription = new CompositeSubscription();
final Subscription subscription = mRepo.find(tId
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<MyResult>() {
                    @Override
                    public void onCompleted() {
                        // Completed
                    }

                    @Override
                    public void onError(Throwable e) {
                        // onError
                    }

                    @Override
                    public void onNext(MyResult result) {
                        //onSuccess
                    }
                });
mCompositeSubscription.add(subscription);
CompositeSubscription mCompositeSubscription=newcompositesubscription();
最终订阅=mRepo.find(tId
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.订阅(新观察员){
@凌驾
未完成的公共无效(){
//完成
}
@凌驾
公共无效申报人(可丢弃的e){
//一个错误
}
@凌驾
public void onNext(MyResult结果){
//成功
}
});
mcompositionsubscription.add(订阅);
您可以检查RxJava+改造+领域的此repo


祝你好运!

不要在
mRealmDataSource.find(tId).subscribeOn(AndroidSchedulers.mainThread())中使用
subscribeOn
就像我说的:

您可以使用
Observable.defer
例如:

class RealmDataSource{
fun find(id: String): Observable<MyResult> {
// Default pattern for loading data on a background thread
return Observable.defer{
                val realm = Realm.getInstance()

                val query = realm
                    .where(MyResult::class.java)

                val flowable =
                    if (realm.isAutoRefresh) {
                        query
                            .findAllAsync()
                            .asFlowable()
                            .filter(RealmResults::isLoaded)
                    } else {
                        Flowable.just(query.findAll())
                    }

                return@defer flowable
                    .toObservable()
            }
}

有关更多信息,请参见

…是否真的是您的
本地
可观察到使用了改装?谢谢,我也支持并尝试了它,但我的应用程序的行为变得奇怪,只有concat中的第一个可观察到的功能起作用。我确信我正在做其他事情,但我已经更改了最初的实现。无论如何,谢谢。