Android 我们是否有可能在OkHttp拦截器中停止请求?
在我们的应用程序中,我们遇到了一个特殊情况-如果我们的Android 我们是否有可能在OkHttp拦截器中停止请求?,android,retrofit,rx-java,okhttp,Android,Retrofit,Rx Java,Okhttp,在我们的应用程序中,我们遇到了一个特殊情况-如果我们的app.specialFlag==true,我们需要停止来自代码的任何请求。我们认为,在这种情况下,最好的方法是包括特殊的拦截器,它将阻止我们的任何请求,类似这样的: if (App.specialFlag) { // Somehow stop request } else { return chain.proceed(chain.request()); } public Observable<User> get
app.specialFlag==true
,我们需要停止来自代码的任何请求。我们认为,在这种情况下,最好的方法是包括特殊的拦截器,它将阻止我们的任何请求,类似这样的:
if (App.specialFlag) {
// Somehow stop request
} else {
return chain.proceed(chain.request());
}
public Observable<User> getUserDetails() {
if (App.specialFlag) {
return Observable.just(null);
}
return api.getUserDetails();
}
另外,我们应该注意,我们使用RxJavaCallAdapterFactory
将响应包装到Observable
s中
但我们在OkHttp拦截器中没有看到任何停止请求的方法
我们想出了两种解决问题的方法:
a) 创建特殊的ApiService.class
,将每个请求包装到我们的API中,如下所示:
if (App.specialFlag) {
// Somehow stop request
} else {
return chain.proceed(chain.request());
}
public Observable<User> getUserDetails() {
if (App.specialFlag) {
return Observable.just(null);
}
return api.getUserDetails();
}
public Observable getUserDetails(){
如果(应用程序specialFlag){
返回可观察值。just(null);
}
返回api.getUserDetails();
}
但我们认为这是一个丑陋而繁琐的解决方案
b) 在拦截器中抛出一个RuntimeException
,然后在我们使用API的每个地方捕获它
第二种解决方案也不是很好,因为我们需要在我们的链中包含大量的onErrorResumeNext
操作符
也许有人知道,如何以更“聪明”的方式处理我们的处境
提前谢谢
我建议将控制逻辑脚本放在OkHttp之外,因为它只用于发出http请求。如何触发请求以及如何处理响应以更新UI,它不需要关心
如果需要,可以创建一个继承自okhttp3.Interceptor的类,然后重写函数intercept并将控制逻辑脚本放入其中
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.addInterceptor(new Interceptor())
.build();
防止请求被执行(在开始之前)的一种方法是简单地按您尝试的方式执行,但添加了:
编辑2019年9月26日
更新了答案,并提供了中提到的详细信息。中缺少的一件事是您需要指定协议和消息。如果您没有指定将得到一个异常。看起来像这样:
if (App.specialFlag) {
// Somehow stop request
} else {
return chain.proceed(chain.request());
}
public Observable<User> getUserDetails() {
if (App.specialFlag) {
return Observable.just(null);
}
return api.getUserDetails();
}
if(App.specialFlag){
返回新的响应。Builder()
.code(418)//任何代码
.body(ResponseBody.create(null,“”)//任何主体
.protocol(protocol.HTTP_2)
.消息(“虚拟响应”)
.request(chain.request())
.build();
}否则{
返回chain.procedue(chain.request());
}
谢谢您的回答!值得注意的是,这仅适用于应用程序拦截器-网络拦截器要求您只调用chain.procedure()
一次,否则会引发运行时异常。@MatBos,当内容长度:0
kotlin时,针对同一问题的任何解决方案version@binrebin您是指请求或响应的内容长度吗?@MatBos请求的内容长度与最新的OkHttp库一样,也应定义body
。所以在我的例子中,添加.body(ResponseBody.create(MediaType.get(“text/html;charset=utf-8”),“”)解决了这个问题。感谢您的帮助。更新版本中需要+1个正文ResponseBody.create(null,”)
工作,无需创建MediaType对象。这没有帮助。当您重写截取
时,问题就会发生,因为您需要返回一个响应。因此,当超时时,通常会抛出异常,这最终会导致应用程序崩溃。这就是为什么这个解决方案是@Bobstring发布的。