领域 - 反应性扩展RxJava2

时间:2017-11-15 18:15:16

标签: realm rx-java2

我将Realm与RxJava2结合使用。 Realm的实例必须由程序员关闭还是自动关闭?

我对这条链有问题:

 return Observable.merge(
      getEvents
        .toObservable()
      ,
      mChangeEventsNotification
        .flatMapMaybe(notification ->
          getEvents
          .firstElement()
        )
    )

Realm抛出java.lang.IllegalStateException:此Realm实例已被关闭,使其无法使用。

getEvents的实现与getList()相同。

我观看了RealmObservableFactory的实现。

运算符firstElement可以关闭第一个Observable合并运算符的Realm Instance吗?

Realm实例在一个线程中的所有观察者之间共享?

它看起来像Realm 4.3.3版的bug。当我降级到版本4.1.0时,每个方面都可以。也许引用计数问题。

1 个答案:

答案 0 :(得分:1)

要回答您的问题,我会询问Rx集成的源代码:

public Flowable<RealmResults<E>> asFlowable() {
    if (realm instanceof Realm) {
        return realm.configuration.getRxFactory().from((Realm) realm, this);

RxObservableFactory默认为RealmObservableFactory,其中包含:{/ p>

@Override
public <E> Flowable<RealmResults<E>> from(final Realm realm, final RealmResults<E> results) {
    final RealmConfiguration realmConfig = realm.getConfiguration();
    return Flowable.create(new FlowableOnSubscribe<RealmResults<E>>() {
        @Override
        public void subscribe(final FlowableEmitter<RealmResults<E>> emitter) throws Exception {
            // Gets instance to make sure that the Realm is open for as long as the
            // Observable is subscribed to it.
            final Realm observableRealm = Realm.getInstance(realmConfig);
            resultsRefs.get().acquireReference(results);
            final RealmChangeListener<RealmResults<E>> listener = new RealmChangeListener<RealmResults<E>>() {
                @Override
                public void onChange(RealmResults<E> results) {
                    if (!emitter.isCancelled()) {
                        emitter.onNext(results);
                    }
                }
            };
            results.addChangeListener(listener);

            // Cleanup when stream is disposed
            emitter.setDisposable(Disposables.fromRunnable(new Runnable() {
                @Override
                public void run() {
                    results.removeChangeListener(listener);
                    observableRealm.close();
                    resultsRefs.get().releaseReference(results);
                }
            }));

            // Emit current value immediately
            emitter.onNext(results);

        }
    }, BACK_PRESSURE_STRATEGY);
}

在这种情况下会发生的事情是,您调用asFlowable() on的RealmResults的Realm实例用于获取其RealmConfiguration,并且在创建Flowable的线程上增加引用计数(这是UI线程或处理程序线程。)

这意味着即使以下方案也可行:

public Flowable<List<MyObject>> getList() {
    try(Realm realm = Realm.getDefaultInstance()) {
        return realm.where(MyObject.class)
                    .findAllAsync()
                    .asFlowable()
                    .filter(RealmResults::isLoaded);
    } // auto-close
}

与此Flowable相关联的Realm将保持打开状态,只要您不退订Flowable也是如此。

要回答您的问题,是的,您需要关闭从某处获得RealmResults的Realm实例。