일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 서비스 쓰레드 차이
- 스택 자바 코드
- 객체
- 서비스 vs 쓰레드
- 안드로이드 라이선스
- 플러터 설치 2022
- 2022 플러터 안드로이드 스튜디오
- 안드로이드 유닛 테스트
- rxjava disposable
- Rxjava Observable
- 안드로이드 레트로핏 crud
- 2022 플러터 설치
- 멤버변수
- 안드로이드 os 구조
- 큐 자바 코드
- jvm이란
- 클래스
- android retrofit login
- 스택 큐 차이
- rxjava cold observable
- 안드로이드 레트로핏 사용법
- ar vr 차이
- jvm 작동 원리
- rxjava hot observable
- 자바 다형성
- 안드로이드 유닛테스트란
- ANR이란
- 안드로이드 유닛 테스트 예시
- android ar 개발
- 안드로이드 라이선스 종류
- Today
- Total
나만을 위한 블로그
[Rxjava] Subject, BehaviorSubject란? 본문
안드로이드에서 반응형 프로그래밍을 하기 위한 방법으로 Rxjava가 있다고 이전에 포스팅한 적이 있다.
onlyfor-me-blog.tistory.com/286
나중에 반응형 프로그래밍을 하게 될 일이 생길 수도 있기 때문에 따로 Rxjava 카테고리를 만들어서 따로 기록하려고 한다.
구구단 예제를 찾아서 빌드해보고 코드를 분석해봤는데 전혀 이해가 안 됐기 때문이 가장 크다.
먼저 Subject부터 기록한다.
reactivex.io/documentation/ko/subject.html
Subject란 Observer나 Observable처럼 행동하는 ReactiveX의 일부 구현체에서 사용 가능한 일종의 교각 혹은 프록시다. 왜냐면 Subject는 Observer기 때문에 하나 이상의 Observable을 구독할 수 있고, 동시에 Observable이기도 해서 항목들을 하나하나 거치면서 재배출하고 관찰하며, 새로운 항목들을 동시에 emit(방출)할 수도 있다
하나의 Subject는 하나의 Observable을 구독하면서, (Observable이 "Cold" Observable인 경우 즉, 옵저버가 구독을 시작하기 전까지 항목들의 배출을 지연시키는 Observable일 경우) Observable이 항목들을 배출시키도록 동작시킨다. 그 결과로 인해 원래는 "Cold" Observable이었던 주제를 "Hot" Observable로 만들기도 한다.
cold와 hot의 차이는 아래와 같다.
youngest-programming.tistory.com/390
cold는 구독하기 전까지 데이터를 방출하지 않는 Lazy한 접근법이고 hot은 구독자의 존재 여부에 상관없이 데이터를 발행하는 Observable이다
cold를 사용하는 예시는 웹 요청, DB 쿼리, 파일 읽기 등이고 hot을 사용하는 예시는 마우스 / 키보드 / 시스템이벤트, 센서 데이터 등이 있다
www.tutorialspoint.com/rxjava/rxjava_subjects.htm
Subject는 Observable, Observer로 모두 행동할 수 있다
Subject는 Observer, Observable이 모두 될 수 있는 요소인 듯하다.
이 Subject의 종류는 총 4가지 있는데 공식 홈페이지에선 아래와 같이 설명하고 있다.
AsyncSubject : 소스 Observable로부터 배출된 마지막 값(만)을 배출하고 소스 Observable의 동작이 완료된 후에야 동작한다. 만약 소스 Observable이 아무 값도 배출하지 않으면 AsyncSubject 역시 아무 값도 배출하지 않는다. 또한 AsyncSubject는 맨 마지막 값을 뒤이어 오는 Observer에 전달하는데, 만약 소스 Observable이 오류로 인해 종료될 경우, AsyncSubject는 아무 항목도 배출하지 않고 발생한 오류를 그대로 전달한다
BehaviorSubject : Observer가 BehaviorSubject를 구독하기 시작하면 옵저버는 소스 Observable이 가장 최근에 발행한 항목(또는 아직 아무 값도 발행되지 않았다면 맨 처음 값이나 기본 값)의 발행을 시작하며 그 이후 소스 Observable(들)에 의해 발행된 항목들을 계속 발행한다. 소스 Observable이 오류 때문에 종료되면 BehaviorSubject는 아무런 항목도 배출하지 않고 소스 Observable에서 발생한 오류를 그대로 전달한다
PublishSubject : 구독 이후에 소스 Observable(들)이 배출한 항목들만 옵저버에게 배출한다. 주의할 점은 PublishSubject는 (이를 막지 않는 이상) 생성 시점에서 즉시 항목들을 배출하기 시작할 것이고 이런 특성 때문에 주제가 생성되는 시점과 옵저버가 이 주제를 구독하기 시작하는 그 사이에 배출되는 항목들을 잃어버릴 수 있다는 단점이 있다. 따라서, 소스 Observable이 배출하는 모든 항목들의 배출을 보장해야 한다면 Create를 사용해서 명시적으로 "차가운" Observable(항목들을 배출하기 전에 모든 옵저버가 구독을 시작했는지 체크한다)을 생성하거나, PublishSubject 대신 ReplaySubject를 사용해야 한다. 소스 Observable이 오류 때문에 종료되면 BehaviorSubject는 아무런 항목도 배출하지 않고 소스 Observable에서 발생한 오류를 그대로 전달한다.
ReplaySubject : 옵저버가 구독을 시작한 시점과 관계 없이 소스 Observable(들)이 배출한 모든 항목들을 모든 옵저버에게 배출한다.
ReplaySubject는 몇 개의 생성자 오버로드를 제공하는데, 이를 통해 재생 버퍼의 크기가 특정 이상으로 증가할 경우 또는 처음 배출 이후 지정한 시간이 경과할 경우 오래된 항목들을 제거한다.
만약, ReplaySubject을 옵저버로 사용할 경우, 멀티 스레드 환경에서는 Observable 계약 위반과 주제에서 어느 항목 또는 알림을 먼저 재생해야 하는지 알 수 없는 모호함이 동시에 발생할 수 있기 때문에 (비순차적) 호출을 유발시키는 onNext(또는 그 외 on) 메서드를 사용하지 않도록 주의해야 한다.
www.tutorialspoint.com/rxjava/rxjava_subjects.htm
Subject 이름 | 설명 |
PublishSubject | 구독 후 방출되는 항목만 배출한다 |
ReplaySubejct | Observable을 구독한 시기에 상관없이 소스 Observable에서 방출한 모든 항목을 방출한다 |
BehaviorSubject | 구독 시 가장 최근 항목을 내보낸 다음 소스 Observable에서 방출한 항목을 계속 방출한다 |
AsyncSubject | 방출이 완료된 후 소스 Observable이 방출한 마지막 항목을 방출한다 |
이 4가지 Subject 중 내가 예제에서 사용한 Subject는 Behavior Subject기 때문에 이를 먼저 확인한다.
www.tutorialspoint.com/rxjava/rxjava_behaviorsubject.htm
BehaviorSubject는 가장 최근에 관찰한 항목을 방출한 다음 모든 후속 관찰 항목을 구독한 각 관찰자에게 방출한다
stackoverflow.com/questions/39494058/behaviorsubject-vs-observable
BehaviorSubject의 고유 기능은 아래와 같다.
1. next()를 받지 않은 경우에도 구독 시 항상 값을 반환해야 하므로 초기값이 필요하다
2. 구독 시 주제의 마지막 값을 반환한다. 일반 Observable은 onNext()를 수신할 때만 트리거된다
3. 언제든 getValue()를 써서 관찰할 수 없는 코드에서 주제의 마지막 값을 검색할 수 있다
또한 BehaviorSubject의 asObservable()을 통해 BehaviorSubject에서 Observable을 가져올 수 있다. Observale은 제네릭이고 BehaviorSubject는 특정 품질(specific qualities)을 가진 Observable의 하위 유형이기 때문에, 기술적으로 BehaviorSubject는 Observable의 하위 유형이다
스택오버플로우의 답변대로 BehaviorSubject는 처음에 초기값을 설정해줄 수 있다.
방법은 create() 또는 createDefault()를 사용하는 것인데, 두 메서드의 차이는 공식 문서를 확인한 결과 아래와 같다
reactivex.io/RxJava/javadoc/io/reactivex/subjects/BehaviorSubject.html#create--
create() : 기본 항목 없이 BehaviorSubject를 만든다
createDefault(T defaultValue) : 관찰한 마지막 항목과 구독하는 각 Observer에 모든 후속 항목을 방출하는 BehaviorSubject를 만든다
- defaultValue : BehaviorSubject가 소스 Observable에서 항목을 아직 관찰하지 않은 한, 모든 Observer에게 먼저 방출될 항목
'개인 공부 > Rxjava' 카테고리의 다른 글
[Rxjava] 연산자의 종류와 생성 연산자(create, interval, just) (0) | 2021.05.26 |
---|---|
[Rxjava] Observable이란? - 2 - (0) | 2021.05.26 |
[Rxjava] Observable이란? - 1 - (0) | 2021.05.26 |
[Rxjava] 인텔리제이에서 Rxjava 사용하기 (0) | 2021.05.25 |
[Rxjava] Rxjava를 사용한 구구단 예제 (0) | 2021.05.08 |