본문 바로가기

안드로이드/RxAndroid(RxJava)

[RxJava] Cold Observable과 Hot Observable

Cold Observable

Cold Observable은 이전 포스팅에서 다룬 것과 같이 Observable에 subscribe를 요청하면 아이템을 발행하기 시작한다. 아이템은 처음부터 끝까지 발행되고, 임의로 종료시키지 않는 이상 여러 번의 요청에도 처음부터 끝까지 발행하는 것을 보장한다.

다음은 interval을 통해 1초마다 아이템을 발행하는 예시이다.

Observable src = Observable.interval(1, TimeUnit.SECONDS);
src.subscribe(value -> System.out.println("First: " + value));
Thread.sleep(3000);
src.subscribe(value -> System.out.println("Second: " + value));
Thread.sleep(3000);


//실행결과
First: 0
First: 1
First: 2
First: 3
Second: 0
First: 4
Second: 1
First: 5
Second: 2

처음 구독 후, 3초 뒤 새로운 구독자로 구독한다. Observable 객체가 동일한지, 아닌지에 상관 없이 모두 처음부터 끝까지 발행하는 것을 볼 수 있다. 같은 src를 사용했음에도 처음부터 시작하는 이유는 각각의 observer마다 다른 observable 소스가 생성되기 때문이다.

 

데이터 기반의 Observable은 대부분 Cold Observable로 만들어진다. HTTP의 GET, DB의 쿼리와 같이 동일한 Observable 객체에서 서로 다른 결과를 생성할 때 처럼 Cold 속성을 지닌다. 실사용 예시로는 Retrofit, Room 등이 존재한다.

 

 

Hot Observable

Hot Observable은 아이템 발행히 시작된 이후로 모든 구독자에게 동시에 같은 아이템을 발행한다. 따라서, 늦게 구독한 observer는 구독 이전에 발행한 아이템을 놓치게 된다.

 

일반적인 예시로는 안드로이드의 UI 이벤트가 존재한다. 안드로이드에서 클릭 이벤트가 발생할 경우 observer가 구독한 후 이벤트만 수신하는 용도로만 사용하며, 이를 재생하기 위해 캐싱을 할 필요는 없다. 

 

Hot Observable을 구현하기 위해 ConnectableObservable이라는 특수한 유형의 Observable을 사용한다.

 

publish() 연산자와 connect() 연산자

위에서 언급한 ConnectableObservable의 주요 특징은 구독을 요청해도 바로 데이터를 발행하지 않는다는 점이다. 우선 publish() 연산자를 통해 일반 Observable을 Hot Observable로 변환한다. 이후 connect() 연산자를 호출하면 그 때 부터 아이템을 발행하기 시작한다.

ConnectableObservable src = 
	Observable.interval(1, TimeUnit.SECONDS)
	.publish()

src.connect()
src.subscribe(value -> System.out.println("First: " + value));
Thread.sleep(3000);
src.subscribe(value -> System.out.println("Second: " + value));
Thread.sleep(3000);


//실행결과
First: 0
First: 1
First: 2
First: 3
Second: 3
First: 4
Second: 4
First: 5
Second: 5

뒤늦게 추가된 구독자는 0~2를 수신하지 못하는 것을 확인할 수 있다.

 

autoConnect() 연산자

autoConnect는 connect 없이 구독 즉시 아이템을 발행하는 연산자이다. autoConnect에는 인자를 전달할 수 있는데 이는 아이템을 발행하는 수를 의미한다. 만약 autoConnect(2)라면, 구독자가 2개가 붙는 후 부터 아이템을 발행한다.

Observable<Long> src = 
    Observable.interval(1, TimeUnit.SECONDS)
    .publish()
    .autoConnect(2);

src.subscribe(value -> System.out.println("First: " + value));
src.subscribe(value -> System.out.println("Second: " + value));
Thread.sleep(3000);


//실행결과
First: 0
Second: 0
First: 1
Second: 1
First: 2
Second: 2

위에서 첫번째 구독자가 붙더라도 아이템을 발행하지 않아 콘솔에 아무것도 출력되지 않는다.

 

요약

  • Cold Observable: 일반 동영상
  • Hot Observable: 스트리밍, ConnectedObservable 활용

 

Reference

  • 아키텍처를 알아야 앱 개발이 보인다.

'안드로이드 > RxAndroid(RxJava)' 카테고리의 다른 글

[RxJava] Scheduler  (0) 2020.12.25
[RxJava] Disposable  (0) 2020.12.22
[RxJava] Observable  (0) 2020.12.21
[RxJava] 반응형 프로그래밍  (0) 2020.12.21