RxJava как шина событий в проекте Android - удалить событие из шины

Раньше я работал с EventBus, который был прост в использовании и понятен. На этот раз, однако, я хотел бы попробовать RxJava для связи, подобной шине событий, однако не очень ясно, как удалить события из RxJava или, лучше сказать, как это должно быть правильно спроектировано, чтобы иметь поведение, подобное тому, что имеет EventBus. когда я позвоню removeStickyEvent?

В RxJava я могу использовать BehaviorSubject для ответа последним, даже если я подписан на этот наблюдаемый объект, но что мне делать, когда это событие обрабатывается? Что делать, если я не хочу, чтобы это событие снова воспроизводилось?

Например, один фрагмент запускает событие, а затем завершает работу. Другой фрагмент прослушивает это событие и обрабатывает его. Затем, если это приложение снова запускает это «другое» действие из других обстоятельств, оно снова подпишется на тот же BehaviorSubject и снова обработает это устаревшее событие, чего мне бы не хотелось.

Я использовал этот проект в качестве ссылки https://github.com/marwinxxii/AndroidRxSamples/blob/master/app/src/main/java/com/github/marwinxxii/rxsamples/EventBusSampleActivity.java


person Sergei Ledvanov    schedule 06.06.2016    source источник
comment
Извините за отсутствие ответа, но... возможно, вам будет проще изучить идею RxJava, ее идиоматическое использование и шаблоны, вместо того, чтобы пытаться повторно реализовать другой шаблон, который может просто не иметь смысла в RxJava.   -  person Marcin Koziński    schedule 06.06.2016


Ответы (1)


Пока вы не планируете, чтобы ваш events был null, я думаю, этого можно добиться довольно легко.

Точно, как вы сказали, вы можете использовать BehaviorSubject для распространения событий sticky, а когда вы хотите removeStickyEvent из bus, вы можете просто создать объект null (чтобы «сбросить» subject).

Что-то вроде этого (из головы - не проверено, без дженериков, просто простой пример, основанный на Object-событии):

public class RxEventBus {

    PublishSubject<Object> eventsSubject = PublishSubject.create();
    BehaviorSubject<Object> stickyEventsSubject = BehaviorSubject.create();

    public RxEventBus() {
    }

    public Observable<Object> asObservable() {
        return eventsSubject;
    }

    public Observable<Object> asStickyObservable() {
        return stickyEventsSubject.filter(new Func1<Object, Boolean>() {
            @Override
            public Boolean call(Object o) {
                return o != null;
            }
        });
    }

    public void postEvent(@NonNull Object event) {
        eventsSubject.onNext(event);
    }

    public void postStickyEvent(@NonNull Object stickyEvent) {
        stickyEventsSubject.onNext(stickyEvent);
    }

    public void removeStickyEvent(){
        stickyEventsSubject.onNext(null);
    }
}
person Bartek Lipinski    schedule 07.06.2016
comment
это интересная концепция. Спасибо. - person Sergei Ledvanov; 07.06.2016
comment
Теперь я думаю.... если я использую BehaviorSubject и мое приложение отправляет два сетевых вызова к разным службам, а затем переходит к другому действию, то, если это другое действие будет прослушивать эти два события, оно получит только ОДНО необработанное событие, а не два. Это не хорошо AFAIK. Можно ли как-то это обойти? - person Sergei Ledvanov; 10.07.2016
comment
используйте 2 темы :) или даже лучше github.com/apptik/rxHub для обработки всех видов случаев - person kalin; 15.09.2016