我有下一个代码。
private val observeRefresh = detailView.observeRefresh
.observeOn(Schedulers.io())
.map { _ -> detailModel.forecastCity }
.flatMap { city ->
detailModel.getForecast(city.id, FORECAST_COUNT)
.map { response -> DetailUiModel.stateSuccess(response.list, detailModel.forecastCity) }
.onErrorReturn { t -> DetailUiModel.stateError(t.message) }
.observeOn(AndroidSchedulers.mainThread())
.startWith(DetailUiModel.stateLoading)
}
.subscribe { this.handleResponse(it) }
private fun handleResponse(model: DetailUiModel) {
detailView.setLoading(model.isLoading)
when {
model.success -> detailView.setForecastItems(model.data!!)
!model.isLoading -> detailView.showError(model.error)
model.city != null -> detailView.setMapImage(createMapUrl(model.city!!))
else -> return
}
}
我想调试此行detailView.setMapImage(createMapUrl(model.city!!))
当我添加检查点应用程序时抛出错误CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
如果我没有添加检查点应用程序正常工作。
答案 0 :(得分:1)
flatMap
可能不会从接收项目的同一个线程中发出,因此您必须通过flatMap
运算符后面的观察来确保在所需的线程上接收到事件:
detailView.observeRefresh
.observeOn(Schedulers.io())
.map { _ -> detailModel.forecastCity }
.flatMap { city ->
detailModel.getForecast(city.id, FORECAST_COUNT)
.map { response ->
DetailUiModel.stateSuccess(response.list,
detailModel.forecastCity)
}
.onErrorReturn { t -> DetailUiModel.stateError(t.message) }
}
.startWith(DetailUiModel.stateLoading) // <---------------------------
.observeOn(AndroidSchedulers.mainThread()) // <---------------------------
.subscribe { this.handleResponse(it) }
不再需要内部observeOn
,此外,建议您在startWith
之前移出observeOn
以确保初始状态信号也到达在observeRefresh
开始之前纠正线程。
答案 1 :(得分:0)
您应该在observeOn(AndroidSchedulers.mainThread())
之前添加.subscribe { this.handleResponse(it)
这是完整的代码:
private val observeRefresh = detailView.observeRefresh
.observeOn(Schedulers.io())
.map { _ -> detailModel.forecastCity }
.flatMap { city ->
detailModel.getForecast(city.id, FORECAST_COUNT)
.map { response -> DetailUiModel.stateSuccess(response.list, detailModel.forecastCity) }
.onErrorReturn { t -> DetailUiModel.stateError(t.message) }
.observeOn(AndroidSchedulers.mainThread())
.startWith(DetailUiModel.stateLoading)
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe { this.handleResponse(it) }