Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 我们是否有可能在OkHttp拦截器中停止请求?_Android_Retrofit_Rx Java_Okhttp - Fatal编程技术网

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发布的。