여기서 설명하는 건 JakeWharton의 RxJava용 RxRelay입니다.

RxRelay를 이용하면 Subscribe중인 여러 Observer에게 계속해서 onNext() 이벤트를 전달할 수 있다. 기존의 RxJava의 Observable과 같은 타입들은 onComplete()된 이후에는 더이상 값을 전달하지 않는다. Relay는 onComplete와 onError()가 없다.

사용 예를 들어보자, 내가 동영상 액티비티에서 좋아요를 눌렀고 이후 내가 좋아요를 누른 영상 목록 액티비티로 이동한다. 이곳에서 내가 방금 좋아요를 누른 영상의 좋아요를 취소한다. 그러면 다시 이전 동영상 액티비티로 돌아왔을 때, 동영상의 좋아요가 취소된 상태가 돼야한다.

이걸 구현하기 위한 제일 간단한 방법은 액티비티가 화면에 시될 때마다(resume) 필요한 데이터를 API에서 다시 불러오면 된다. 근데 이렇게 매번 API를 요청하면 트래픽 낭비요, 비동기처리가 되는 동안은 좋아요 표시가 남아있거나 로딩화면을 띄워야한다(…). 매번 이렇게 하기보다 아래의 방법을 사용한다.

  1. 두 액티비티가 동영상 정보를 구독한다(Subscribe or Observe)
  2. 좋아요 버튼을 누르면 동영상 정보를 갱신한다.
  3. 구독중인 액티비티에 갱신 이벤트가 전달된다.
  4. 두 액티비티는 바뀐 정보를 저장하고, UI를 갱신한다.
  5. UI가 사라지면 dispose()로 구독을 해제해서 메모리 릭을 방지한다.

이거를 지금 Realm을 통해 하도록 되어있는데, Realm의 data가 invalid되면서 UncheckedRow 예외가 가끔 발생하는 문제가 있어서 이걸 RxRelay로 바꿀까 고민중이다. Realm을 쓰면 로컬DB에 데이터를 저장할 경우 자동으로 구독자들에게 이벤트가 날아가서 캐싱되는 효과도 덤으로 얻을 수 있어서 편리했는데, RxRelay를 쓰게되면 데이터의 저장/삭제/변경마다 이벤트를 전송하는 부분을 추가해야한다.

아래는 전부 JakeWharton의 RxRelay GitHub Repository의 README에 있는 예제코드이다. 3가지 Relay 타입이 있는데 필요에 따라 적절히 쓰면 될 듯

PublishRelay

PublishRelay<Object> relay = PublishRelay.create();
// observer1 will receive all events
relay.subscribe(observer1);
relay.accept("one");
relay.accept("two");
// observer2 will only receive "three"
relay.subscribe(observer2);
relay.accept("three");

BehaviorRelay

// observer will receive the "one", "two" and "three" events, but not "zero"
BehaviorRelay<Object> relay = BehaviorRelay.createDefault("default");
relay.accept("zero");
relay.accept("one");
relay.subscribe(observer);
relay.accept("two");
relay.accept("three");

위 예제에서 관측자는 zero를 제외한 one, two, three를 전달받는다.

ReplayRelay

ReplayRelay<Object> relay = ReplayRelay.create();
relay.accept("one");
relay.accept("two");
relay.accept("three");
// both of the following will get the events from above
relay.subscribe(observer1);
relay.subscribe(observer2);

observer1, observer2는 one, two, three를 모두 전달받을 수 있다. 기본으로 크기제한은 없지만, 최대 기록 가능한 버퍼의 크기를 지정할 수도 있다.

Relay 클래스를 상속해서 직접 만들 수도 있다.

References

Written by

2020.12.8 ~ 2022.6.9 군복무중 Serving in the South Korean Military Service

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store