[RxJava] RxProgramming, Observable

이영한·2021년 12월 20일
3

RxJava

목록 보기
1/3
post-thumbnail

1. 리액티브 프로그래밍

안드로이드 앱에서는 어쩔 수 없이 비동기 프로그래밍이 필요하다. 왜냐하면 클릭, 스크롤, 드래그 등 여러 이벤트가 비동기적으로 들어오기 때문이다. 그래서 Rx 프로그래밍이 유용하게 적용될 수 있다.

리액티브 프로그래밍은 코드를 순서대로 한 줄씩 읽어가며 진행되는 명령형 프로그래밍과 다르다. 아래 예시를 살펴보자

a := b + c

b와 c의 합을 a에 대입하는 간단한 예시다.

기존의 명령형 프로그래밍이라면 a에 한 번 값이 할당 된 후에는 b,c가 바뀌어도 a의 값이 바뀌지 않을 것이다.

하지만 리액티브 프로그래밍에서는 데이터의 변화를 중시한다. b,c에 변화가 생기면 이들의 합으로써 정의된 a도 영향을 받는다.

리액티브 프로그래밍에 대한 여러 설명이 있지만 데이터의 흐름에 따라 계속 함수를 처리한다는 점이 중요한 것 같다.

안드로이드에서는 리액티브 프로그래밍을 위해 RxJava를 사용한다. 아래 라이브러리를 build.gradle에 추가하여 사용할 수 있다

implementation "io.reactivex.rxjava2:rxjava:2.2.7"

2. Observable

Observable은 데이터의 흐름을 의미한다. 즉 리액티브 프로그래밍에서 가장 중요한 존재라고 볼 수 있다.

1) just

Observable을 만드는 가장 간단한 함수는 just 이다.

Observable.just(1,2,3)

just 함수는 말 그대로 '그저' 데이터를 발행한다는 것이다. 위 코드는 1,2,3을 차례로 발행한다.

데이터를 발행하면 이 데이터를 사용할 함수를 정해야 한다. 이는 'subscribe'를 통해 지정할 수 있다.

Observable.just(1,2,3).subscribe(System.out::println);

코드를 실행하면 예상대로 1,2,3이 출력된다.

실행결과
1
2
3

2) fromArray

Java를 사용한다면 Array는 거의 무조건 쓰게 된다. 이렇게 친숙한 Array로 부터 Observable을 얻어낼 수 있다

String[] arr = {"array1", "array2", "array3"};
Observable.fromArray(arr).subscribe(System.out::println);

Observable.fromArray함수를 사용했다. 이 함수는 Observable 클래스에 있는 static 함수로 array를 Observable로 만들어준다.

3. Cold Observable, Hot Observable

Observable의 종류에는 두 가지가 있다. Cold와 Hot이다.

Cold Observable은 subscribe 함수를 통해 관찰을 시작해야 데이터를 발행하는 Observable이다. 앞서 언급한 just, fromArray로 만든 Observable은 subscribe를 호출해야 데이터를 발급했다.
이러한 Observable들이 Cold Observable이다.

Hot Observable은 따로 관찰을 하지 않아도 데이터를 계속 발행한다. 흔히 예시로 드는게 시간, 주식 가격 등이 있다. 우리가 딱히 관심을 두고 바라보고 있지 않아도 Hot Observable은 계속 새로운 데이터를 만들어낸다.

근데 RxJava에서 제공하는 대부분의 함수는 Cold Observable이다. just, fromArray처럼 말이다.

그래서 Hot Observable을 만들기 위해서는 특수한 클래스가 필요하다.

4. Subject, ConnectableObservable

RxJava에서 Hot Observable을 만들기 위해 제공하는 특수한 클래스에는 Subject와 ConnectableObservable이 있다.

1) Subjet

subject는 Observable로도 쓸 수 있고 Observer로도 쓸 수 있는 특이한 클래스다. 그렇기에 Cold Observable과 이를 Hot Observable로 쓰고 싶은 사용자(Observer)의 중간다리 역할을 할 수 있다.
즉, Observable을 사용자 대신 구독하고 있다가 사용자가 구독을 시작하면 실시간 정보를 보내주는 것이다.

예시를 살펴보자

PublishSubject subject = PublishSubject.create();
 Observable.interval(10, TimeUnit.MILLISECONDS)
           .subscribe(subject);
Thread.sleep(100);
subject.subscribe(System.out::println);
Thread.sleep(100);

새롭게 나온 클래스와 함수를 알아보자

  • PublishSubject : 발생한 데이터를 그대로 Observer에게 전달하는 subject 클래스
  • interval() : 특정 시간 간격으로 0부터 데이터를 생성하는 Observer를 만드는 함수. 코드에서는 10ms 간격으로 데이터를 만든다.

여기서 Observable.interval을 Hot Observable로 쓰고 싶다.

하지만 interval도 Cold Observable이기 때문에 subscribe를 호출해야 데이터가 발행된다.

그래서 PublishSubject가 중간에서 100ms 먼저 구독을 시작하여 100ms가 경과된 시간의 데이터를 System.out::println이 얻을 수 있도록 해준다.

실행결과는 아래와 같다

실행결과
10
11
12
13
14
15
16
17
18
19

0부터가 아닌 100ms 지난 후 발행하는 10부터 출력된다. 즉 Hot Observable로써 동작 한 것이다.

2) ConnectableObservable

connectable Observable은 connect()를 부른 시점부터 데이터를 발행한다. 이런 점에서 subject보다 더 직관적으로 사용할 수 있는 것 같다.

ConnectableObservable connectableObservable1 = Observable.interval(10, TimeUnit.MILLISECONDS).publish();
connectableObservable1.connect();
Thread.sleep(100);  
connectableObservable1.subscribe(System.out::println);
Thread.sleep(100);
  • publish() : Observable에서 ConnectableObservable을 만들어준다.

코드를 살펴보면 connectsbleObservable을 만들고 connect를 바로 호출한다.
이 시점부터 데이터는 발행되는 것이다.

이후 subject 예시와 마찬가지로 100ms간 sleep을 시키고 로그 출력 함수를 subscribe시킨다.
결과는 아래와 같다.

실행결과
10
11
12
13
14
15
16
17
18
19


[참고자료]

Reactive Programming Wiki
RxJava 프로그래밍

profile
간단하게 개발하고 싶습니다

0개의 댓글