Rxjava + Realm从错误的线程访问

rgu*_*rra 3 android realm rx-java rx-java2

我正在从Realm读取/写入这个异常

06-19 09:49:26.352 11404-11404/******E/ContentValues:loadData:OnError Realm从错误的线程访问.Realm对象只能在创建它们的线程上访问.java.lang.IllegalStateException:从错误的线程访问Realm.Realm对象只能在创建它们的线程上访问.在io.realm.BaseRealm.checkIfValid(BaseRealm.java:385)的io.realm.alalm.OrderedRealmCollectionImpl.size(OrderedRealmCollectionImpl.java:307)中的io.realm.RealmResults.isLoaded(RealmResults.java:115). RealmResults.size(RealmResults.java:60)位于/******.lambda $ loadData $ 0(SplashPresenter.java:42)的/./的.***$ Lambda $ 1.test(未知来源)at io.reactivex.internal.operators.observable.ObservableFilter $ FilterObserver.onNext(ObservableFilter.java:45)at io.reactivex.observers.SerializedObserver.onNext(SerializedObserver.java) :111)ato.reactivex.internal.operators.observable.ObservableDelay $ DelayObserver $ 1.run(ObservableDelay.java:84)at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:59)at io.reactivex .internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:51)at java.util.concurrent.FutureTask.run(FutureTask.java:237)at java.util.concurrent.ScheduledThreadPoolExecutor $ Schedul edFutureTask.run(ScheduledThreadPoolExecutor.java:272)java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)java.lang上的java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:607) .Thread.run(Thread.java:761)

这是代码:

  mSubscribe = Observable.just(readData())
            .delay(DELAY, TimeUnit.SECONDS)
            .filter(value -> !value.isEmpty())
            .switchIfEmpty(createRequest())
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread()).subscribe(data -> {
                getView().hideLoading();
                writeData(data);
            }, 
           (throwable -> {
            }));
Run Code Online (Sandbox Code Playgroud)

读数据

  private List<CategoryModel> readData() {
    Realm defaultInstance = Realm.getDefaultInstance();
    List<CategoryModel> title = defaultInstance.where(CategoryModel.class).findAllSorted("title");

    defaultInstance.close();
    return title;
}
Run Code Online (Sandbox Code Playgroud)

写数据

private void writeData(List<CategoryModel> categoryModels) {

        try {
            Realm defaultInstance = Realm.getDefaultInstance();
            defaultInstance.executeTransactionAsync(realm -> realm.insertOrUpdate(categoryModels));
            defaultInstance.close();
        } finally {
            getView().notifyActivity(categoryModels);
        }
    }
Run Code Online (Sandbox Code Playgroud)

如何使用正确的线程遵循此逻辑?

Aje*_*ary 6

跨线程使用Realm的唯一规则是记住Realm,RealmObject或RealmResults实例不能跨线程传递.

当您想要从不同的线程访问相同的数据时,您应该只需获取一个新的Realm实例(即Realm.getDefaultInstance())并通过查询获取对象(然后在线程的末尾关闭Realm).

对象将映射到磁盘上的相同数据,并且可以从任何线程读取和写入!您还可以使用后台线程运行你的代码realm.executeTransactionAsync()这样 .