onNext() никогда не вызывается для PublishSubject
Я пытаюсь построить презентатор, который вычисляет некоторые события за определенный период времени, показывает загрузку только при первой загрузке и обновляет пользовательский интерфейс, когда это будет сделано. Поскольку события могут обновляться несколькими способами (например, пользовательскими настройками), я должен быть в состоянии сообщить докладчику, что события были обновлены и что он должен обновить их снова. Вот что у меня сейчас есть:
subject
.map<List<UpcomingRowViewModel>> {
provider.calculateEventsBetween(TimePeriod.aYearFrom(firstDay))
}
.doOnSubscribe {
view.showLoading()
}
.observeOn(resultScheduler)
.subscribeOn(workScheduler)
.subscribe { upcomingRowViewModels ->
view.display(upcomingRowViewModels)
}
subject.onNext(TRIGGER)
Предметом является PublishSubject
Инт. Я делаю onNext()
сразу после подписки, потому что я хочу, чтобы данные обновлялись сразу после их подписки.
Приведенный выше код творит чудеса в моих модульных тестах, а также только тогда, когда я запускаю его на устройстве с подключенным отладчиком. Если я просто запускаю его (без какого-либо отладчика), он достигает view.showLoading()
часть, но никогда provider.calculateEventsBetween(TimePeriod.aYearFrom(firstDay)
Таким образом, пользовательский интерфейс застревает с загрузкой.
Есть идеи?
1 ответ
Вероятная причина, по которой вы не видите звонка .subscribeOn(workScheduler)
, Применив это к Subject
который сам по себе не имеет практического применения, так как при подписке на Subject
Вы задерживаете подписку на Subject
достаточно того, что onNext
колл не найдет ни одного наблюдателя в этот момент.
То, что вы, вероятно, хотите, что-то вроде этого:
subject
.observeOn(resultScheduler) // <--------------- (1)
.doOnNext {
view.showLoading()
}
.observeOn(workScheduler) // <--------------- (2)
.map<List<UpcomingRowViewModel>> {
provider.calculateEventsBetween(
TimePeriod.aYearFrom(firstDay))
}
.observeOn(resultScheduler) // <--------------- (3)
.subscribe { upcomingRowViewModels ->
view.display(upcomingRowViewModels)
}
subject.onNext(TRIGGER)
Вместо doOnSubscribe
, который выполняется один раз, (1) гарантирует, что когда есть работа, эмиссия onNext субъекта вызовет индикатор загрузки в главном потоке (при условии, что resultScheduler равен AndroidSchedulers.mainThread
в не тестах). Затем вы захотите выполнить сопоставление основного потока и, таким образом (2) переместить элемент в фоновый поток. Как только сопоставление произошло, полученный элемент снова перемещается в основной поток в (3), где ваш вид может отобразить его.