Есть ли у нас возможность прекратить запрос в OkHttp Interceptor?
В нашем приложении мы встретились с одним специальным случаем - если наш App.specialFlag == true
, нам нужно остановить любой запрос из нашего кода. И мы думаем, что наилучшим подходом в этой ситуации является специальный Interceptor
, который остановит любые наши запросы, примерно так:
if (App.specialFlag) {
// Somehow stop request
} else {
return chain.proceed(chain.request());
}
Кроме того, следует отметить, что мы используем RxJavaCallAdapterFactory
для переноса ответов в Observable
s.
Но мы не видим никаких методов для остановки запроса в OkHttp Interceptors.
Мы разработали два способа решения нашей проблемы:
a) Создайте специальный ApiService.class
для упаковки каждого запроса в нашем API следующим образом:
public Observable<User> getUserDetails() {
if (App.specialFlag) {
return Observable.just(null);
}
return api.getUserDetails();
}
Но мы считаем, что это уродливое и громоздкое решение.
b) Бросьте a RuntimeException
в Interceptor, а затем поймайте его в любом месте, где мы используем наш API.
Второе решение также не очень хорошо, потому что нам нужно включить в наши цепочки множество операторов onErrorResumeNext
.
Может кто-нибудь знает, как справиться с нашей ситуацией более "умным" способом?..
Спасибо заранее!
Ответы
Ответ 1
Один из способов предотвратить выполнение запроса (до его запуска) - просто выполнить, как вы пытались, но с добавлением Response.Builder:
if (App.specialFlag) {
return new Response.Builder()
.code(600) //Simply put whatever value you want to designate to aborted request.
.protocol(Protocol.HTTP_2)
.message("Dummy response")
.request(chain.request())
.build();
} else {
return chain.proceed(chain.request());
}
ОБНОВЛЕНИЕ 26/09/2019 Обновленный ответ с деталями, упомянутыми Bobstring
Ответ 2
Одна из недостатков в принятом ответе заключается в том, что вам нужно указать протокол и сообщение. Если вы не укажете, что получите Исключение. Выглядит так:
if (App.specialFlag) {
return new Response.Builder()
.code(418) //Whatever code
.protocol(Protocol.HTTP_2)
.message("Dummy response")
.request(chain.request())
.build();
} else {
return chain.proceed(chain.request());
}
Ответ 3
-
Я бы предложил поставить логику управления script за пределы OkHttp, так как она используется только для создания HTTP-запроса. Как инициировать запрос и как обрабатывать ответ для обновления пользовательского интерфейса, его не нужно заботиться,
-
Если вы хотите, вы можете создать класс, унаследованный от okhttp3.Interceptor, затем переопределить функцию перехвата и поместить свою логику управления script внутрь.
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.addInterceptor(new Interceptor())
.build();