ReactiveX #03 - RxBus
안드로이드에서는 복잡해지기 쉬운 Component 간 이벤트 전달을 간편하게 구현하기 위해 Event Bus 라이브러리를 이용할 수 있습니다.
greenrobot의 EventBus와 square의 Otto가 많이 쓰이거나 쓰여왔는데 작년부터 Otto는 Deprecated 되었습니다. Deprecated에 그치지 않고 RxJava와 RxAndroid를 이용하라고 권장하고 있습니다.
이번 글에서는 Event Bus의 개념과 Rx를 이용한 Event Bus 구현법에 대해 알아보겠습니다.
Event Bus라는 용어를 안드로이드 이외 다른 분야에서도 쓰고 있는데, 찾아보니 EventBus는 하나의 기술적인 용어나 특별한 의미를 가진 용어는 아녔습니다.
엄밀히 따지면 Event Bus는 Publisher-Subscriber 패턴을 이용한 이벤트 전달 중개자입니다.
Publisher-Subscriber 패턴은 특정 클래스에서 일어나는 이벤트들을 감지한다는 점에서 Observer 패턴과 비슷합니다.
차이점은 Subject가 이 이벤트들을 어디로 전달할지 알아야 하는 Observer 패턴과 달리, Publisher-Subscriber 패턴에서는 이 이벤트들을 "broadcasting" 한다는 점에 초점을 맞추기 때문에 Publisher가 이벤트들을 어디로 전달할지 알 필요가 없습니다.
결국 Publisher와 Subscriber 간 직접적인 의존성을 줄여주기 때문에 두 로직 간 독립적으로 구현할 수 있지만, Publisher와 Subscriber 사이의 중개자(MiddleMan)가 필요합니다.
이 중개자가 Event Bus입니다.
RxJava를 이용한 Event Bus 구현법에 대해 설명하겠습니다.
우선 중개자(MiddleMan)인 RxBus 클래스를 구현해야 합니다.
// this is the middleman object
public class RxBus {
private final Subject<Object, Object> bus = new SerializedSubject<>(PublishSubject.create());
public void publish(Object o) {
bus.onNext(o);
}
public Observable<Object> toObserverable() {
return bus;
}
}
RxBus 클래스를 기반으로 이벤트를 전달(publish)하는 부분입니다.
@OnClick(R.id.btn_demo_rxbus_tap)
public void onTapButtonClicked() {
rxBus.publish(new TapEvent());
}
RxBus 클래스를 기반으로 이벤트를 전달받는 부분입니다.
// note that it is important to subscribe to the exact same _rxBus instance that was
// used to post the events
rxBus.toObserverable()
. subscribe(new Action1<Object>() {
@Override
public void call(Object event) {
if (event instanceof TapEvent) {
showTapText();
} else if (event instanceof SomeOtherEvent) {
doSomethingElse();
}
}
});
RxBus 입장에서는 이벤트를 구독하는 Subsriber들이 있는지 파악할 필요가 있습니다.
이때는 SerializedSubject의 hasObservers() API를 통해 리턴되는 boolean 값을 통해 파악할 수 있습니다.