实际上,我已经创建了RxSearch类型的配置。我在其中附加了一个Edittext textChangeListener和PublishSubject。使用事件将字符发送到Observable,该字符将用作改良API调用的输入。
问题
我面临的唯一问题是,有时我会从可观察到的onError()回调中的API“错误的流结束”中得到错误。一旦收到错误,Observable将停止工作。 Observable关闭,无法从PublishSubject的onNext()中获取字符。
查看 RxSearchObservable
class RxSearchObservable {
companion object {
fun fromView(editText: EditText): Observable<String> {
val subject = PublishSubject.create<String>()
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
//subject.onComplete()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
//subject.onNext(s.toString())
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (s.isNotEmpty()) subject.onNext(s.toString())
}
})
return subject
}
}
}
我如何在侧面SwitchMap中订阅和进行Retrofit API调用。
RxSearchObservable.fromView(edtToolSearch)
.debounce(700, TimeUnit.MILLISECONDS)
.distinctUntilChanged()
.retryWhen { t -> t.delay(3, TimeUnit.SECONDS) }
.switchMap { searchTerm ->
runOnUiThread { progressBar.visibility = View.VISIBLE }
apiManager.getSearchUnits(searchTerm)
}
.onErrorResumeNext(Observable.empty())
.subscribe({ response ->
Log.i("Called subscribe", ":::::::::::+++++++++++++++ GONE")
progressBar.visibility = View.GONE
if (response.isSuccessful) {
val units = response.body()
val searchedDatasets = units?.dataset
if (searchedDatasets?.size!! > 0) {
val searchAdapter = SearchAdapter(this@MapActivity, searchedDatasets, false)
listSearch.visibility = View.VISIBLE
listSearch.adapter = searchAdapter
} else {
toast("No items found !!!")
}
} else {
apiError = ErrorUtils.parseError(response)
toast(apiError.msg)
}
}, { t: Throwable? ->
progressBar.visibility = View.GONE
toast(t?.message.toString())
}))
任何想法,帮助,建议将不胜感激。预先感谢。
答案 0 :(得分:0)
错误终止的流。您可以retry()
进行订阅,但这仅应有条件地完成。也许有超时,也许只有几次,也许只有某些错误。
根据您的情况,您应该考虑处理switchMap
中的API调用错误。像这样,错误不会到达主流。
.switchMap { searchTerm ->
runOnUiThread { progressBar.visibility = View.VISIBLE }
apiManager.getSearchUnits(searchTerm)
.onErrorResumeNext(Observable.empty())
}