-
RxJava: Subject, PublishSubject, BehaviorSubject개발/안드로이드 2020. 2. 15. 17:14
0. Subject
RxJava에서 Subject 클래스는 구독하고 있는 관찰자(Observer)에게 새로운 값을 전달 할 때 사용하는 클래스다. 따로 Observable로 새로운 값을 만들 필요 없이 Subject 객체에 내장된 onNext 함수로 새로운 값을 옵저버에게 전달할 수 있기 때문에 짧은 코드로도 reactive하게 구현하는 것이 가능하다. 안드로이드에서 제공하는 LiveData와 유사한 역할을 한다.
아래 코드는 Subject 클래스중 하나인 PublishSubject를 이용해서 새로운 값을 갱신하는 예제다.
class Person { var publishName: PublishSubject<String> = PublishSubject.create() } val person = Person() person.publishName.subscribe { Log.d(TAG, "publishName: " + it) } person.publishName.onNext("selfish") person.publishName.onNext("developer")
실행결과 다음과 같이 수정된 값이 출력되는 것을 확인 할 수 있다.
1. PublishSubject vs BehaviorSubject
RxJava에서 제공하는 Subject 함수로 AsyncSubject, PublishSubject, BehaviorSubject, RelaySubject가 있는데 이번 포스트에서는 가장 많이 사용되는 PublishSubject와 BehaviorSubject를 그리고 둘 간의 차이를 소개해보려고 한다. 그런데 바로 글로 쓰는 것 보다는 코드와 출력되는 결과를 보면서 설명을 하는게 더 좋을 것 같다.
class Person { var behaviorName: BehaviorSubject<String> = BehaviorSubject.create() var publishName: PublishSubject<String> = PublishSubject.create() fun nextName(name: String) { behaviorName.onNext(name) publishName.onNext(name) } } person.nextName("selfish") person.publishName.subscribe { Log.d(TAG, "publishName: " + it) } person.behaviorName.subscribe { Log.d(TAG, "behaviorName: " + it) } person.nextName("developer")
Person 클래스에는 BehaviorSubject 객체를 선언해뒀고 Subject 객체의 값을 한 번에 바꾸고자 nextName이라는 함수를 만들었다. 그리고 아래 코드에서는 publishName과 behaviorName을 구독하도록 했는데 기존 코드와 달리 구독하기 전에 이름을 "selfish"로 갱신을 미리 해뒀다.
이 코드의 출력 결과는 다음과 같다.
BehaviorSubject로 선언 된 객체는 구독 전에 갱신한 "selfish" 문자열을 출력하는 반면 PublishSubject로 선언 된 객체는 구독 이후에 갱신한 "developer" 문자열만 출력하고 있다. 이는 두 객체의 동작 구조가 다르기 때문이다.
2. PublishSubject
PublishSubject 객체의 경우 구독 이후에 갱신된 값에 대해서만 값을 받는다. 아래 다이어그램의 세번째 줄에서 구독하기 이전에 갱신된 빨간공, 초록공은 무시하고 파란 공만 받고 있는 것을 볼 수 있다. 과거에 데이터를 무시하고 새로 갱신되는 값만 보고 싶은 경우 사용하기 유용하다. 대표적으로 버튼을 클릭하는 이벤트를 PublishSubject로 사용하기도 한다.
3. BehaviorSubject
BehaviorSubject 객체의 경우에는 구독하는 시점의 가장 최근에 갱신된 값을 받는다. 다이어그램 세번째 줄에서 구독하면서 가장 최근에 갱신된 초록색 공과 그 이후에 갱신된 파란색 공을 받는것을 볼 수 있다. 구독하는 시점에서 과거에 갱신된 데이터중 가장 최근의 값이 필요할 때 써먹으면 유용하다.
그림 출처
'개발 > 안드로이드' 카테고리의 다른 글
Exoplayer에 stetho 적용하기 (0) 2020.03.16 MotionLayout 으로 간단하게 animation 만들기 (0) 2020.03.08 RxJava: defer, fromCallable (0) 2020.02.15 코틀린 apply, also, let, run, with (0) 2020.02.09 수직으로 스와이프 가능한 ViewPager 만들기 (0) 2019.12.07