在我们的应用程序中,我们遇到了一个特殊情况 - 如果我们的
App.specialFlag == true
,我们需要停止来自我们代码的任何请求。我们认为,在这种情况下最好的方法是包含特殊的Interceptor
,这将停止我们的任何请求,像这样:
if (App.specialFlag) {
// Somehow stop request
} else {
return chain.proceed(chain.request());
}
此外,我们应该注意,我们使用
RxJavaCallAdapterFactory
将响应包装到 Observable
s 中。
但是我们在 OkHttp 拦截器中没有看到任何停止请求的方法。
我们想出了两种方法来解决我们的问题:
a) 创建特殊的
ApiService.class
来包装我们 API 中的每个请求,如下所示:
public Observable<User> getUserDetails() {
if (App.specialFlag) {
return Observable.just(null);
}
return api.getUserDetails();
}
但我们认为这是丑陋和麻烦的解决方案。
b) 在 Interceptor 中抛出一个
RuntimeException
,然后在我们使用 API 的每个地方捕获它。
第二个解决方案也不好,因为我们需要在我们的链中包含很多
onErrorResumeNext
运营商。
可能有人知道,如何以更“聪明”的方式处理我们的情况?..
提前致谢!
接受的答案中缺少的一件事是您需要指定协议和消息。如果您不指定,您将获得异常。看起来像这样:
if (App.specialFlag) {
return new Response.Builder()
.code(418) // Whatever code
.body("".toResponseBody(null)) // Whatever body
.protocol(Protocol.HTTP_2)
.message("Dummy response")
.request(chain.request())
.build();
} else {
return chain.proceed(chain.request());
}
防止请求被执行(在它开始之前)的一种方法是简单地按照您尝试的方式执行,但添加了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
提到的详细信息我建议将控制逻辑脚本放在 OkHttp 之外,因为它仅用于发出 http 请求。如何触发请求,如何处理响应来更新UI,不需要关心;
如果你愿意,你可以创建一个继承自okhttp3.Interceptor的Class,然后覆盖函数拦截并将你的控制逻辑脚本放在里面。
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.addInterceptor(new Interceptor())
.build();