我有一个类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
}
但是订阅者没有收到该事件。为什么呢?
答案 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);
}
}