Activity 中的(替代)或(正确使用)AndroidObservables

(Alternative to) or (proper use of ) AndroidObservables in Activity

我一直在使用 AndroidObservables 进行需要在 UI 线程之外发生的操作。我现在发现自己处于这种情况:我需要在主线程外做一个操作,然后根据结果更改 UI。我的尝试是这样的:

subscription = AndroidObservable.bindActivity(this, Observable.just(null))
    .observeOn(Schedulers.io())
    .subscribe(new Action1<Object>() {
      @Override
      public void call(Object o) {
        if (doCheckThatMustBeOffMainThread()) {
          doSomethingWithTheUI();
        }
      }
    });

这是有问题的,因为我现在正在与主线程之外的 UI 进行交互。

我使用 AndroidObservables 的部分原因是我知道(认为?)我可以通过取消订阅 onDestroy() 来避免内存泄漏,但考虑到 AndroidObservable 的这种使用看起来是多么人为(创建一个发出 null 的 observable……)并且我无法在主线程上与 UI 交互,这让我认为可能有更合适的使用 AndroidObservables 的方法——或者另一种方法是也可以防止内存泄漏。这些可能是什么?

您需要将检查移动到它自己的 Observable。这样你就可以控制它运行的调度程序。

Observable<Boolean> doCheckObservable =
        Observable
                .create(new Observable.OnSubscribe<Boolean>() {
                    @Override
                    public void call(Subscriber<? super Boolean> subscriber) {
                        // Runs on the io thread when subscribed to.
                        // Do check that returns true or false.
                        subscriber.onNext(doCheckThatMustBeOffMainThread());
                        subscriber.onCompleted();
                    }
                })
                .subscribeOn(Schedulers.io());

Subscription subscription =
        AndroidObservable
                .bindActivity(this, doCheckObservable)
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean doThatCheckPassed) {
                        if (doThatCheckPassed) {
                            // bindActivity() makes this run on the main thread.
                            doSomethingWithTheUI();
                        }
                    }
                });
// NOTE: This is now AppObservable in the latest RxAndroid release.
AndroidObservable.bindActivity(this, Observable.defer(
    new Func0<Observable<Void>>() {

      @Override
      public Observable<Void> call() {
        return doCheckThatMustBeOffMainThread() ?
            Observable.just(null) : Observable.empty();
      }

    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<Void>() {

      @Override
      public void call(Void unused) {
        doSomethingWithTheUi();
      }

    }));

这样你仍然通过一个可观察对象推送 null,但这次它只是被用作一个信号,并且工作发生在你需要它的地方:在 io land 中签出,以及在UI 个线程。