Rxjava2 取消订阅方式

2,192 阅读3分钟

取消订阅方式:

在RxJava 1的时候我们知道在你用Observable执行时候会返回一个Subscription类: Subscription subscription = Observable.xxx("yy").subscribe(.....); 复制代码然后我们只需要在我们界面的ondestory方法中对这个对象进行取消订阅操作就可以:

@Override
protected void onDestroy() {

if (subscription != null && !subscription.isUnsubscribed) {
    subscription. unsubscribe();
}

super.onDestroy();

}

我们可以看到很简单,这样当我们Activity关闭的时候已经自动取消了订阅。 而RxJava2换了方式,但是基本方法是一模一样的,只是换成了Disposable: 如果我们使用的是Consumer,那和原来RxJava 1 是一样的操作:

Disposable disposable = Observable.just(1).subscribe(new Consumer() {

@Override
public void accept(@NonNull Integer integer) throws Exception {

}

});

//取消订阅 if(disposable != null && !disposable.isDisposed()){

 disposable.dispose();

}

但是我们可能更多的是使用Observer等,那这时候subscrbe(observer)返回的是void,所以不能像上面一样操作,需要下面代码所示那样: private Disposable disposable; Observable.just(1).subscribe(new Observer() {

   @Override
   public void onSubscribe(Disposable d) {
        disposable = d;
   }

   @Override
   public void onNext(Integer integer) {}

   @Override
   public void onError(Throwable e) {}

   @Override
   public void onComplete() {}

});

//然后在需要取消订阅的地方调用即可

if(disposable != null && !disposable.isDisposed()){

 disposable.dispose();

}

和RxJava 1 最大的区别主要是获取这个取消订阅对象的地方不同,Disposable是在Observer里面的onSubscribe方法的参数拿到,然后我们可以定义一个临时变量进行赋值,然后在需要取消订阅的地方去调用即可。 但是很多人会说难道不能和RxJava 1 的方式差不多,因为很多项目已经按照RxJava 1 的方式来封装了进行相应的取消订阅代码,直接换成RxJava 2 方式变化不一样了,能不能变得和Rxjava 1 取消订阅方式差不多 。答案是当然可以。 我们可以使用DisposableObserver和subscribeWith二者结合来做的和Rxjava 1 一样的方式来取消订阅。

1.1 DisposableObserver

DisposableObserver 是一个抽象的 Observer, 它通过实现了 Disposable 接口允许异步取消。

/**

  • An abstract {@link Observer} that allows asynchronous cancellation by implementing Disposable.

  • @param the received value type */ public abstract class DisposableObserver implements Observer, Disposable {

    final AtomicReference s = new AtomicReference();

    @Override public final void onSubscribe(Disposable s) { if (DisposableHelper.setOnce(this.s, s)) { onStart(); } }

    /**

    • Called once the single upstream Disposable is set via onSubscribe. */ protected void onStart() { }

    @Override public final boolean isDisposed() { return s.get() == DisposableHelper.DISPOSED; }

    @Override public final void dispose() { DisposableHelper.dispose(s); } } 我们可以看到,这个DisposableObserver即实现了Observer,又实现了Disposable接口。

//比如这个是我们的Observer

DisposableObserver observer = new DisposableObserver() {

  @Override
  public void onNext(Object o) {}
  @Override
  public void onError(Throwable e) {}
  @Override
  public void onComplete() {}

};

//把我们的Observer对Observable进行订阅
Observable.just(1).subscribe(observer);

//然后在需要取消订阅的地方对这个observer进行取消订阅即可。

observer.dispose();

1.2 subscribeWith

public final <E extends Observer<? super T>> E subscribeWith(E observer) {

 subscribe(observer);
 return observer;

}

我们可以看到 subscribeWith订阅的源码是把Observer对象同时返回,正好配合上面的DisposableObserver:

DisposableObserver observer = Observable.just(1).subscribeWith(new DisposableObserver() {

 @Override
 public void onNext(Integer integer) {}
 @Override
 public void onError(Throwable e) {}
 @Override
 public void onComplete() {}

});

//需要取消订阅的地方:

observer.disposable();

这下是不是和我们RxJava 1 里面的写法一模一样了。

1.3 CompositeDisposable

我在看很多一些开源项目中,有些人一个界面的上会有多个订阅(比如有多个网络接口请求),这时候我们需要批量取消订阅,有些人会写一个ArrayList,然后把这些上面我们返回的DisposableObserver对象加入到ArrayList中,然后当我们的界面关闭的时候,再遍历ArrayList,把里面的元素取出来一个个取消订阅。实际上RxJava 2 中有替我们考虑到这个需求。那便是CompositeDisposable类。

CompositeDisposable compositeDisposable = new CompositeDisposable();

//批量添加 compositeDisposable.add(observer1);

compositeDisposable.add(observer2);

compositeDisposable.add(observer2);

//最后一次性全部取消订阅

compositeDisposable.dispose();