PublishSubject订阅者未接收事件

时间:2016-11-10 10:44:52

标签: android rx-java

我有一个类ViewModel,它会公开PublishSubject个活页夹。

视图模型

public class ViewModel {

    private PublishSubject<ActionsEvent> binder = PublishSubject.create();
    private Service service = createService();

    @Override
    public Observable<ActionsEvent> getBinder() {
        return binder.doOnSubscribe(initialize());
    }

    private Action0 initialize() {
        return new Action0() {
            @Override
            public void call() {
                service.getActions().subscribe(new Action1<Action>() {
                    @Override
                    public void call(Action action) {
                        Log.d(TAG, "So far, so good");
                        binder.onNext(new ActionFetchedEvent(action));
                    }
                });
            }
        };
    }

}

在Activity中,它订阅了在获取每个事件时要执行的操作。

活动

public class MyActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstance) {
        //More code
        viewModel.getBinder().subscribe(new Action1<ActionsEvent>() {
            @Override
            public void call(ActionsEvent event) {
                Log.d(TAG, "This is not printed!!");
                paintActionInUserInterface(event.getAction());
            }
        });
    }
}

服务

public interface ActionsService {
    @GET("/actions")
    Observable<Action> getActions(); //Performs an HTTP request with Retrofit
}

ActionFetchedEvent

public class ActionFetchedEvent implements ActionsEvent {

    private Action action;

    //getters and setters

}

但是订阅者没有收到该事件。为什么呢?

1 个答案:

答案 0 :(得分:1)

这是因为您没有使用.create()工厂方法创建主题,并且在订阅回调之前将调用onSubscribe,因此您将订阅太晚而错过该元素。您可以使用BahaviourSubject,如果您订阅,它将重播最后一个元素。

你能否告诉我们你想要达到的目标,因为我认为你可以用更好的方式编写观察点,而不是订阅和发布onNext到这个主题。

请看看我的例子。我使用RxJava2作为环境。

public class ViewModelTest {
    class ActionsEvent {
    }

    class ActionFetchedEvent extends ActionsEvent {
        public ActionFetchedEvent(ActionsEvent actionEvent) {

        }
    }

    interface Service {
        public Observable<ActionsEvent> getActions();
    }

    class MyViewModel {
        private BehaviorSubject<ActionsEvent> binder;

        private Service service;

        public MyViewModel(Service service) {
            this.service = service;
            this.binder = BehaviorSubject.create();
        }

        public Observable<ActionsEvent> getBinder() {
            return binder.doOnSubscribe(disposable -> {
                service.getActions().subscribe(action -> {
                            binder.onNext(new ActionFetchedEvent(action));
                        }
                );
            });
        }
    }

    @Test
    public void name() throws Exception {
        Service mock = mock(Service.class);

        MyViewModel viewModel = new MyViewModel(mock);

        when(mock.getActions()).thenAnswer(invocation -> {
            return Observable.just(new ActionsEvent());
        });

        TestObserver<ActionsEvent> test = viewModel.getBinder().test();

        test.assertValueCount(1);
    }
}