RxJava 2 Cancellable 和 Disposable 有什么区别?

What is the difference between RxJava 2 Cancellable and Disposable?

我想使用 RxJava 2 创建一个 Observable 从视图点击侦听器。我从最简单的实现开始(我在这里不使用 lambda 来向您展示此方法中的不同类型):

 Observable<View> viewObservable = Observable.create(new ObservableOnSubscribe<View>() {
        @Override
        public void subscribe(@NonNull ObservableEmitter<View> e) throws Exception {
            mNewWordView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View value) {
                    if (!e.isDisposed()) {
                        e.onNext(value);
                    }
                }
            });
        }
    });

然后我想到了如果不需要进一步设置onClickListener为null的方法。我发现有两种方法具有相似的(对我而言)名称:

e.setCancellable(Cancellable c);e.setDisposable(Disposable d);

它们之间有什么区别,我应该使用哪个?

Cancellable 最终被包裹在 Disposable 中,因此这两个调用的最终效果是相同的。不同之处在于 Disposable 具有更多您可能不想实现的功能,因此可以使用简单的 Cancellable 界面作为替代。

如果你只是想在 observable 结束时处理一些东西,使用 Cancellable。如果您有可能由于某些外部原因而被处置的资源,您希望实施 Disposable 以实施 Disposable.isDisposed() 方法。

请注意,这些方法是互斥的。一次只能注册一个 disposable 或 cancellable。调用两者会覆盖第一个。

来自Javadoc

[Cancellable is] A functional interface that has a single cancel method that can throw.

Disposable 不是函数式接口,而且在实现其 dispose() 方法时,不允许抛出已检查的异常。

相比之下,许多非 RxJava 组件 return a CloseableAutoCloseable 通过 throws IOExceptionthrows Exception 定义并且有点像负担,因为你需要尝试抓住它。

例如,您在处理文件时希望使用 setCancellable

Observable.create((ObservableEmitter<byte[]> e) -> {
    FileInputStream fin = new FileInputStream("raw.dat");
    e.setCancellable(fin::close);

    byte[] buffer = new byte[4096];

    for (;;) {
        int r = fin.read(buffer);
        if (r < 0) {
            break;
        }
        e.onNext(buffer);
    }
    e.onComplete();
});

如果你使用 Scheduler:

,你会使用 setDisposable
Observable.create((ObservableEmitter<Event> e) -> {
    Worker worker = Schedulers.io().createWorker();
    e.setDisposable(worker);

    eventSource.onEvent(es ->
        worker.schedule(() -> e.onNext(es))
    );
});