我正在使用Kotlin,OkHttp,RxJava2开发Android应用程序。
我正在尝试进行自动搜索。
当用户输入字符时,对其进行搜索。
override fun search(subject: PublishSubject<String>) {
disposable.add(
subject.debounce(1000, TimeUnit.MILLISECONDS)
.filter { it.isNotEmpty() }
.distinctUntilChanged()
.switchMap { keyword ->
search(keyword)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response ->
// using the response
}, {
it.printStackTrace()
})
)
}
和搜索功能:
fun search(keyword: String): Observable<String> {
val request = Request.Builder()
.url(url)
.post(RequestBody.create(contentType, xmlBody(keyword)))
.build()
return Observable.fromCallable {
val response = OkHttpClient().newCall(request).execute()
response.body()?.string()
}
}
我喜欢“ Retrofit”,但就我而言,我应该使用XML。我尝试将Retrofit与SimpleXMLConverter一起使用,但是不适合该项目。所以我正在使用“ OkHttp”。但是上面的代码抛出“ InterruptedIOException”。
第一个电话没问题。但是,在处理第一个请求的同时收到下一个搜索请求时,会发生异常。
我该如何解决?
我认为,switchMap应该取消先前的请求,但不是。
您设置的调度程序错误。
您需要:
override fun search(subject: PublishSubject<String>) {
disposable.add(
subject.debounce(1000, TimeUnit.MILLISECONDS)
.filter { it.isNotEmpty() }
.distinctUntilChanged()
.switchMap { keyword ->
search(keyword).subscribeOn(Schedulers.io())
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ response ->
// using the response
}, {
it.printStackTrace()
})
)
}
注意,后台调度程序需要直接在可搜索的内容中设置,而不是在switchmap
之后的链中设置。这是在除主链以外的其他链中执行搜索,否则整个链将被阻塞,swichmap
似乎没有任何作用,因为只有自然完成后才会取消搜索。