RxJava 1 포스트 [Android] RxJava 시작하기
RxJava 2 포스트 [Android] RxJava Observable 옵저버블
RxJava 3 포스트 [Android] RxJava Cold Observable, Hot Observable


Disposable

이전 포스트들에서 Observable 객체에서 발행할 아이템을 정의한 후 subscribe()를 통해 스트림을 생성하고 아이템을 발행했다. 이 subscribe()를 호출한 후에는 Disposable 객체가 반환된다.

Observable source = Observable.just("A", "B", "C");
Disposable disposable = source.subscribe(System.out::println);


만약 Observable이 발행하는 아이템의 개수가 정해져 있다면 모두 발행된 이후 onComplete()가 호출되고 안전하게 종료될 것이다. 하지만 아이템을 무한히 발행하거나 오랫동안 실행되는 Observable의 경우에는 제대로 종료해주지 않는다면 메모리 릭이 발생할 수 있다. 더 이상 옵저버블의 구독이 필요하지 않을 때에는 이를 폐기(dispose)하는 것이 효율적이다. Disposable.dispose()를 호출해서 언제든지 아이템의 발행을 중단할 수 있다.

Observable source = Observable.interval(1, TimeUnit.SECONDS);
Disposable disposable = source.subscribe(System.out::println);

new Thread(() -> {
    try {
        Thread.sleep(3500);
    } catch(Exception e) {
        e.printStackTrace();
    }
    disposable.dispose();
}).start();


interval()을 통해 아이템을 1초마다 발행하도록 하고, 3.5초 뒤에 구독하던 Observable을 dispose 하고 나면 아이템의 발행이 중단되고 모든 리소스가 폐기된다.

리소스가 제대로 폐기되었는지 확인하려면 Disposable.isDisposed()를 통해 체크할 수 있다. dispose() 함수 내부에서는 폐기 여부를 체크하므로, dispose() 호출하기 전에 isDisposed()를 먼저 부를 필요는 없다. 또, onComplete()가 명시적으로 호출된다면 dispose()를 호출할 필요가 없다.


CompositeDisposable

만약 구독자가 여러 곳에 있다면 이들을 폐기할 때마다 각 Disposable 객체의 dispose()를 호출해주어야 한다. 이런 귀찮은 작업을 개발자들이 좋아할 리 없다. 이럴 땐 CompositeDisposable에 각각의 disposable을 추가해둔 후 한꺼번에 폐기하면 된다.

Observable source = Observable.interval(1, TimeUnit.SECONDS);
Disposable disposable1 = source.subscribe(System.out::println);
Disposable disposable2 = source.subscribe(System.out::println);
Disposable disposable3 = source.subscribe(System.out::println);

CompositeDisposable compositeDisposable = new CompositeDisposable();
// add(Disposable) or addAll(Disposable...)
compositeDisposable.add(disposable1);
compositeDisposable.addAll(disposable2, disposable3);

...

compositeDisposable.dispose();


현재 프로젝트에서는 Retrofit을 이용해 여러 통신 작업을 수행한 후, 이를 한꺼번에 dispose 하기 위해서 CompositeDisposable을 사용하고 있다.

안드로이드의 라이프사이클에 맞추려면 onDestroy()에서 compositeDisposable.dispose() 를 호출해 모든 자원을 폐기할 수 있다.


References

  • 옥수환, 『아키텍처를 알아야 앱 개발이 보인다』, 비제이퍼블릭(2020)
  • http://reactivex.io/documentation/operators