Realm访问不正确的线程,当我将两个observable压缩在一起时,单独工作正常

时间:2017-02-03 00:02:12

标签: android multithreading realm

我想调用服务器从两个不同的端点获取数据并将它们压缩在一起,但我收到了臭名昭着的信息:

java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.
02-03 08:18:49.693 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at io.realm.BaseRealm.checkIfValid(BaseRealm.java:383)
02-03 08:18:49.693 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at io.realm.RealmResults.removeChangeListener(RealmResults.java:988)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at io.realm.rx.RealmObservableFactory$5$2.call(RealmObservableFactory.java:151)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.subscriptions.BooleanSubscription.unsubscribe(BooleanSubscription.java:71)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:136)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:72)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.internal.operators.OperatorZip$Zip.tick(OperatorZip.java:252)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.internal.operators.OperatorZip$Zip$InnerSubscriber.onNext(OperatorZip.java:323)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.internal.operators.OperatorMerge$MergeSubscriber.emitScalar(OperatorMerge.java:511)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.internal.operators.OperatorMerge$MergeSubscriber.tryEmit(OperatorMerge.java:466)
02-03 08:18:49.694 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:244)
Caused by: rx.exceptions.OnErrorThrowable$OnNextValue: OnError while emitting onNext value: [Ljava.lang.Object;.class
02-03 08:18:49.695 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:190)
02-03 08:18:49.695 30543-30543/com.zeyad.usecase.accesslayer W/System.err:     at rx.internal.operators.OperatorZip$Zip.tick(OperatorZip.java:257)
02-03 08:18:49.695 30543-30543/com.zeyad.usecase.accesslayer W/System.err:  ... 15 more

当我运行此代码时

Observable.zip(dataUseCase.getObject(new GetRequest.GetRequestBuilder(UserRealm.class, true)
                        .url(String.format(USER, userLogin))
                        .build()), dataUseCase.searchDisk(realm -> realm.where(RepoRealm.class)
                        .equalTo("owner.login", userLogin), RepoRealm.class)
                        .flatMap(list -> Utils.isNotEmpty(list) ? Observable.just(list) :
                                dataUseCase.getList(new GetRequest.GetRequestBuilder(RepoRealm.class, true)
                                        .url(String.format(REPOSITORIES, userLogin))
                                        .build()).doOnSubscribe(() -> Log.d("DB empty", "Calling Server")))
                .flatMap(list -> Utils.isNotEmpty(list) ? Observable.just(list) : 
                dataUseCase.getList(new GetRequest.GetRequestBuilder(RepoRealm.class, true)
                                        .url(String.format(REPOSITORIES, userLogin))
                                        .build()).doOnSubscribe(() -> Log.d("DB empty", "Calling Server"))),
                new Func2<UserRealm, List, UserDetailState>() {
                    @Override
                    public UserDetailState call(UserRealm userRealm, List repos) {
                        return new UserDetailState(userRealm, repos, false, false, null, INITIAL);
                    }
                })

每个dataUseCase方法调用都由

组成
subscribedOn(AndroidSchedulers.from(handlerThread.getLooper()))
.observedOn(AndroidSchedulers.mainThread());

1 个答案:

答案 0 :(得分:1)

您的Realm Observable是

.subscribeOn(AndroidSchedulers.from(handlerThread.getLooper()))
.observeOn(AndroidSchedulers.mainThread());

但它应该是

.unsubscribeOn(AndroidSchedulers.from(handlerThread.getLooper()))
.subscribeOn(AndroidSchedulers.from(handlerThread.getLooper()))
.observeOn(AndroidSchedulers.mainThread());