Retrofit + Debouce на EditText вызывает исключение InterruptedIOException - PullRequest
0 голосов
/ 09 ноября 2018

В настоящее время у меня есть EditText для пользователя, чтобы войти в поиск. Я пытаюсь использовать RxJava с debounce для поиска только так часто, вместо каждого символа. Тем не менее, я получаю InterruptedIOException во время тестирования, что убивает поток.

private val subject = BehaviorSubject.create<String>()

init {
    configureAutoComplete()
}

private fun configureAutoComplete() {
    subject.debounce(200, TimeUnit.MILLISECONDS)
        .flatMap {
            getSearchResults(query = it)
        }
        .subscribe({ result ->
            handleResult(result)
        }, { t: Throwable? ->
            Logger.e(t, "Failed to search")
        })
}

fun getSearchResults(query: String): Observable<List<MyObject>> {
    val service = NetworkService.create() // get retrofit service
    return service.search(query)
}


fun search(text: String) {
    subject.onNext(text)
}

Как видите, я создаю BehaviorSubject, а в init я устанавливаю его с debounce.

getSearchResult возвращает Observable и выполняет мой сетевой запрос.

Но когда я тестирую, если я печатаю с определенной скоростью (обычно быстро, например, набирая другой символ во время выполнения запроса), он выдаст Exception.

 Failed to search : java.io.InterruptedIOException
    at okhttp3.internal.http2.Http2Stream.waitForIo(Http2Stream.java:579)
    at okhttp3.internal.http2.Http2Stream.takeResponseHeaders(Http2Stream.java:143)
    at okhttp3.internal.http2.Http2Codec.readResponseHeaders(Http2Codec.java:125)

Я смотрел на это, https://stackoverflow.com/a/47276430/3106174, и похоже, что я все делаю правильно.

1 Ответ

0 голосов
/ 10 ноября 2018

После дополнительного тестирования я понял, что сетевой запрос был в основном потоке.

Вы можете проверить это, заменив сетевой вызов на Observerable.create{ ... } и добавив внутрь Thread.sleep(1000).

Я следовал этому уроку, https://proandroiddev.com/building-an-autocompleting-edittext-using-rxjava-f69c5c3f5a40,, и один из комментариев упоминал эту проблему.

"Но я думаю, что одна вещь вводит в заблуждение в вашем фрагменте кода, и это что предметы не являются потокобезопасными. И поток, что ваш код будет будет запущен поток, который вы излучаете (в этом случае основной нить). «

Чтобы решить эту проблему, нужно заставить его работать на Schedulers.io(). Убедитесь, что это после debounce или не будет работать.

private fun configureAutoComplete() {
    subject.debounce(200, TimeUnit.MILLISECONDS)
        .observeOn(Schedulers.io()) // add this here
        .distinctUntilChanged()
        .switchMap {
            getSearchResults(query = it)
        }
        .subscribe({ result ->
            handleResult(result)
        }, { t: Throwable? ->
            Logger.e(t, "Failed to search")
        })
}
...