使用rxjava的领域 - 使用其他处理程序线程比使用UI线程更灵活吗?

时间:2016-03-10 07:48:53

标签: android realm rx-java

阅读了Realm的文档(这是非常好的,赞成之后),到目前为止我想到的是:

  1. 领域需要一个处理程序线程来运行,而UI线程将是完美的
  2. 如果您不想通过在UI线程中查询来减慢UI线程,可以使用findAllAsync()或其他类似的方法,这些方法在UI线程上执行查询并将结果返回到UI线程
  3. 现在我的问题不仅仅是“我不想在UI线程中查询”。我希望能够在我创建的处理程序线程中查询域,将结果Observable与在同一处理程序线程上运行的其他处理器Observable链接起来,最后将处理结果传递给UI线程。主要是因为UI线程的处理过于昂贵。

    基本上这样的片段看起来像这样:

    Observable
        .defer(new Func0<Observable<RealmResults<User>>>() {
            @Override
            public Observable<RealmResults<User>> call() {
                Realm realm = Realm.getDefaultInstance();
                return realm.where(User.class).findAll().asObservable();
            }
        })
        .map(new Func1<RealmResults<User>, UserUIData>() {
            @Override
            public UserUIData call(RealmResults<User> users) {
                return new UserUIData(users.first());
            }
        })
        .subscribeOn(MY_HANDLER_THREAD_SCHEDULER)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe();
    

    到目前为止我遇到的两个问题:

    1. 当我取消订阅UI线程时,应用程序会崩溃,因为根据RealmObservableFactory,当取消订阅时,必须在UI线程中删除更改侦听器。在我看来,我们无法改变执行以下哪个调度程序,而且Realm不允许跨线程进行访问/修改,因此崩溃。

      subscriber.add(Subscriptions.create(new Action0() {
          @Override
          public void call() {
              realm.removeChangeListener(listener);
          }
      }));
      
    2. 我无法找到正确关闭Realm实例的方法。

    3. 有人可以帮我指点正确的方向吗?我不应该首先这样做吗?还有更好的方法吗?

      非常感谢。

1 个答案:

答案 0 :(得分:3)

您应该可以使用unsubscribeOn / doOnUnsubscribe这样的组合(未经测试):

AtomReference<Realm> realmRef = new AtomicReference(null);
Observable
    .defer(new Func0<Observable<RealmResults<User>>>() {
        @Override
        public Observable<RealmResults<User>> call() {
            Realm realm = Realm.getDefaultInstance();
            realmRef.set(realm);
            return realm.where(User.class).findAll().asObservable();
        }
    })
    // ...
    .doOnOnsubscribe(realmRef.get().close())
    .unsubscribeOn(MY_HANDLER_THREAD_SCHEDULER)
    .subscribeOn(MY_HANDLER_THREAD_SCHEDULER)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe();

我们在此处遇到一个问题,即可以更轻松地跨线程移动RealmQueries。一旦实现,应该更好地处理这种情况:https://github.com/realm/realm-java/issues/1955