web-dev-qa-db-ja.com

サブスクリプションが完了したらすぐにDisposable.dispose()を呼び出すことをお勧めしますか?

私はActivityを作成し、Singleクラスの複数のインスタンスをサブスクライブしています(それぞれが個別のバックグラウンドスレッドでいくつかの作業を行っています)。サブスクリプションごとに、作成されたDisposableインスタンスを、CompositeDisposableをスコープとするActivityインスタンスに追加します。 Activityが破棄されると、CompositeDisposable.clear()メソッドを呼び出して、Activity内のすべてのサブスクリプションを破棄します。もちろん、これは、すべてのDisposableインスタンス(作業が完了したサブスクリプションのインスタンスを含む)がActivityが破壊されるまで私のActivityに滞留することを意味します。

これは大丈夫ですか、それとも、特定のSingleインスタンスが作業を完了するたびに(つまり、SingleObserveronSuccessを受け取ったときに、個々のサブスクリプションごとにDisposable.dispose()を呼び出しますか?またはonErrorコールバック)?後者のアプローチの問題は、どのDisposableがどのSingleObserverに関連付けられているかを追跡する必要があることです(これはCompositeDisposableを使用するポイントを無効にします)。 Singleインスタンスが作業を完了するたびにサブスクリプションを破棄するためのより良いアプローチはありますか?

14
Adil Hussain

いいえ、できません。Observableが完了すると、Observableはそれ自体で破棄されます。
これは 監視可能な契約の一部です

ObservableがOnErrorまたはOnComplete通知をオブザーバーに発行すると、サブスクリプションが終了します。オブザーバーは、この方法でObservableによって終了されたサブスクリプションを終了するために、購読解除通知を発行する必要はありません。

21
yosriz

Yosrizの答えは正しい答えですが、Disposableサブスクリプションが機能するため、CompositeDisposableインスタンスからSingleインスタンスを削除したい場合は、Disposableを削除してくださいインスタンスがぶらぶらしている)、それから私はこのクラスをまとめました...

public abstract class MySingleObserver<T> implements SingleObserver<T> {

    private Disposable disposable;

    @Override
    public void onSubscribe(@NonNull Disposable disposable) {
        this.disposable = disposable;
        onStart();
    }

    public Disposable getDisposable() {
        return disposable;
    }

    public abstract void onStart();
}

... SingleObserverサブスクリプションに次のようにSingleとして渡すことができます。

Single.just(1)
      .subscribe(new MySingleObserver<Integer>() {

          @Override
          public void onStart() {
              MyActivity.this.myCompositeDisposable.add(getDisposable());
              // do something further
          }

          @Override
          public void onSuccess(@NonNull Integer success) {
              MyActivity.this.myCompositeDisposable.remove(getDisposable());
              // do something further
          }

          @Override
          public void onError(@NonNull Throwable error) {
              MyActivity.this.myCompositeDisposable.remove(getDisposable());
              // do something further
          }
      });
1
Adil Hussain