首页 > 解决方案 > 从compositeDisposable clear 上的错误线程访问领域

问题描述

我正在添加我在活动中订阅的所有观察者都添加到 CompositeDisposable。OnStop 活动正在调用 mCompositeDisposable.clear() ,它会在下面创建崩溃日志。由于 CompositeDisposable.clear 调用 onDispose 请在下面找到对领域的代码

Single.create(...).subscribeOn(Schedulers.io())
                   .observeOn(AndroidSchedulers.mainThread())
                   .subscribe(observer);
mCompositeDisposable.add(observer);

在 Schedulers.io() 中创建领域

Single<RealmList<T>> source ...
source .doOnDispose(() -> {
 if (mRealm == null) {
            return;
        }
 if (Looper.myLooper() != null) {
            mRealm.removeAllChangeListeners();
        }
 if (!mRealm.isClosed()) {
            mRealm.close();
        }
mRealm = null;
}  

给出以下崩溃日志

java.lang.IllegalStateException:来自错误线程的领域访问。

Realm access from incorrect thread.
 Realm objects can only be accessed on the thread they were created.
                                                       at io.realm.BaseRealm.JN(SourceFile:438)
                                                       at io.realm.BaseRealm.removeAllListeners(SourceFile:263)
                                                       at io.realm.Realm.removeAllChangeListeners(SourceFile:1399)
...

 at io.reactivex.internal.operators.single.SingleDoOnDispose$DoOnDisposeObserver.dispose(SourceFile:60)
                                                       at io.reactivex.internal.operators.single.SingleDoFinally$DoFinallyObserver.dispose(SourceFile:85)
                                                       at io.reactivex.internal.disposables.DisposableHelper.aq(SourceFile:124)
                                                       at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.dispose(SourceFile:78)
                                                       at io.reactivex.internal.disposables.DisposableHelper.aq(SourceFile:124)
                                                       at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.dispose(SourceFile:78)
                                                       at io.reactivex.internal.disposables.DisposableHelper.aq(SourceFile:124)
                                                       at io.reactivex.internal.operators.single.SingleObserveOn$ObserveOnSingleObserver.dispose(SourceFile:87)
                                                       at io.reactivex.internal.disposables.DisposableHelper.aq(SourceFile:124)
                                                       at io.reactivex.observers.DisposableObserver.dispose(SourceFile:91)
                                                       at io.reactivex.disposables.CompositeDisposable.a(SourceFile:240)
                                                       at io.reactivex.disposables.CompositeDisposable.clear(SourceFile:206)

尝试使用 .unsubscribeOn(Schedulers.io()) 但没有奏效

标签: androidrealmrx-java2realm-mobile-platformrealm-list

解决方案


在 Schedulers.io() 中创建领域

您正在创建 Realm 的实例,mainThread然后要求 Realm 在io线程中操作(例如加载数据),这在 Realm 设计中是不可能的。Realm 开发人员的示例说明这里有几点需要牢记https://github.com/realm/realm-java/tree/master/examples/rxJavaExample

在您的代码片段中实施第 1 点和第 4 点,我们将为我们提供正确的解决方案。请注意,该方法findAllAsync()将为您异步执行所有操作,无需io使用 RxJava 创建线程

    Single<RealmList<T>> realmResults = realm.where(....)
                .equalTo(...)
                .findAllAsync()
                .asFlowable()
                .map { realmResult->
                    val realmList = RealmList<T>()
                    realmList.addAll(realmResult.toList())
                    return realmList
                }
                .firstOrError()

            realm.close()

推荐阅读