CompositeDisposable은 여러 Disposable 객체를 한 곳에서 관리할 수 있는,
RxJava의 유용한 클래스입니다.
이 CompositeDisposable에 dispose()함수를 사용하면,
구독을 해제하고 관련리소스를 해제해 줍니다.
dispose는 '처분하다', '처리하다'의 뜻을 가지고 있기도 하지요.
그런데, clear()라는 메소드도 있습니다.
메소드 이름만 보면 둘 다 비슷한 의미를 가지고 있는 것 같은데,
어떻게 다른 걸까요?
오늘 글에서 보겠습니다.
1. dispose()
dispose()는,
현재 CompositeDisposable에 추가된 모든 Disposable을 해제하고,
CompositeDisposable 자체도 해제하는 강력한 메소드입니다.
여기서 말하는 Disposable은,
Observable, Single, Maybe, Completable, Flowable 타입들이,
구독(subscribe)할 때, 반환하는 객체를 말합니다.
dispose()함수를 사용하면 다음과 같은 효과를 얻을 수 있습니다.
- CompositeDisposable이 완전히 해제되어 더 이상 사용할 수 없음
- add() 메서드를 호출해도 새로운 Disposable 추가 불가함
- 이미 해제된 CompositeDisposable에 add()를 호출해도 해당 Disposable은 즉시 해제(dispose)됨
- isDisposed() 메서드 사용시 true값 반환
코드를 보며 이해해 보겠습니다.
onCreate에서,
Observable이 반환하는 disposable객체를 변수 disposable에 담은 다음,
compositeDisposable객체에 담았습니다.
이후 onDestroy에서,
dispose()함수를 통해서 모든 disposable객체와 관련 리소스들을 해제하였습니다.
private val compositeDisposable = CompositeDisposable()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_simple)
val disposable = Observable.just("Hello, RxJava!")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ result -> Log.d("TAG", "result") },
{ error -> Log.d("TAG", error.message)}
compositeDisposable.add(disposable)
}
override fun onDestroy() {
super.onDestroy()
compositeDisposable.dispose()
}
안드로이드에서 RxJava를 사용할 경우,
onDestroy()는 액티비티 생명주기의 끝단이므로,
dispose()를 사용하여 모든 Disposable객체 뿐만이 아니라,
compositeDisposable까지 해제하는 것이 적합합니다.
2. Clear()
dispose()와 비슷한 clear()메소드는 아래와 같은 특징을 가지고 있습니다.
- 추가된 모든 Disposable()해제
- CompositeDisposable 자체는 해제되지 않음
- 추후에 새로운 Disposable을 add() 메서드를 통해 추가 가능
- isDisposed() 메서드사용시 false 반환
추가된 disposable객체들을 해제하는 것은 모두 같지만,
CompositeDisposable자체는 해제시키않아서,
추후에 다시 추가할 수 있다는 것이 특징입니다.
실제 코드에서 어떻게 사용하는지 보겠습니다.
clear()는 이름은 쉽지만,
dispose()보다는 좀 더 특수한 경우에 사용합니다.
아래처럼 해제했다가, 다시 추가하는 경우에 사용하기 적합하기 때문입니다.
class ExampleFragment : Fragment() {
private val compositeDisposable = CompositeDisposable()
override fun onCreateView(...): View? { ... }
override fun onViewCreated(...) {
...
startObservations()
}
private fun startObservations() {
// 5초마다 데이터를 발행하는 Observable
val disposable = Observable.interval(5, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { count -> Log.d("TAG", "Received count: $count") }
compositeDisposable.add(disposable)
}
override fun onDestroyView() {
super.onDestroyView()
compositeDisposable.clear() // View가 파괴될 때 모든 구독 해제
}
override fun onViewStateRestored(...) {
super.onViewStateRestored(...)
// Fragment가 백스택에서 복원될 때 compositeDisposable에 추가
if (view != null) {
startObservations()
}
}
}
3. clear vs dispose
둘을 표로 비교해보면서 이해해 보겠습니다.
dispose | clear | |
재사용 가능여부 | CompositeDisposable이 해제되어 재사용 불가 |
CompositeDisposable은 유효하며, 재사용 가능 |
결과 | isDisposed()는 true를 반환 | isDisposed()는 false를 반환 |
새로운 Disposable 추가 |
add()를 호출해도 새로운 Disposable이 즉시 해제 |
add()를 통해 새로운 Disposable을 추가 가능 |
사용처 | 액티비티나 프래그먼트가 완전히 종료되 더 이상 CompositeDisposable이 필요 없을 때 메모리 누수를 방지하고자 할 때 |
액티비티나 프래그먼트가 일시적으로 중지되었다가 다시 시작될 때 기존의 CompositeDisposable을 재사용하고 싶을 때 현재의 구독을 모두 해제하고, 이후에 새로운 구독을 추가하여 계속 관리하고자 할 때 |
다시 한번 정리하면,
CompositeDisposable을 재사용할 필요가 없고,
더 이상 구독을 관리하지 않아도 될 때,
특히 android의 onDestroy()같은 곳에서,
dispose()를 사용하는 것이 적절하구요.
compositeDisposable로,
여러 disposable객체들을 한번에 해제했다가,
다시 compositeDisposable에 추가하는 등의 재사용이 필요할 때는,
clear()를 사용해 주면 됩니다.
'Android 개발 > RxJava, RxAndroid' 카테고리의 다른 글
RxJava fromAction()과 andThen() 으로 구현하는 순차적 실행 코드 (0) | 2024.11.08 |
---|---|
RxJava concatMap 정리: flatMap과 비교하며 이해하기 (0) | 2024.11.03 |
RxJava flatMapCompletable 과 flatMap + ignoreElement 조합의 차이 이해하기 (0) | 2024.11.02 |
RxJava ignoreElements() 연산자에 대한 이해 (1) | 2024.10.30 |
댓글