我们是否有可能在OkHttp拦截器中停止请求?

Pav*_*nko 15 android rx-java retrofit okhttp

在我们的应用程序中,我们遇到了一个特例 - 如果App.specialFlag == true我们需要,我们需要停止来自代码的任何请求.我们认为,在这种情况下,最好的方法是包括特殊的Interceptor,这将阻止我们的任何请求,如下所示:

if (App.specialFlag) {
    // Somehow stop request
} else {
    return chain.proceed(chain.request());
}
Run Code Online (Sandbox Code Playgroud)

另外,我们应该注意,我们RxJavaCallAdapterFactory用于将响应包装到Observables中.

但我们没有看到任何在OkHttp拦截器中停止请求的方法.

我们提出了两种方法来解决我们的问题:

a)创建特殊ApiService.class用于包装我们的API中的每个请求,如下所示:

public Observable<User> getUserDetails() {
    if (App.specialFlag) {
        return Observable.just(null);
    }
    return api.getUserDetails();
}
Run Code Online (Sandbox Code Playgroud)

但我们认为这是一个丑陋而繁琐的解决方案.

b)RuntimeException在Interceptor中抛出一个,然后在我们使用API​​的每个地方捕获它.

第二种解决方案也不好,因为我们需要onErrorResumeNext在链中包含很多运算符.

可能有人知道,如何以更"聪明"的方式处理我们的情况?

提前致谢!

Mat*_*Bos 21

防止请求被执行的一种方法(在它启动之前)它只是按照您的尝试进行,但添加了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());
}
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,这仅适用于*application*拦截器 - *network*拦截器要求您只调用一次`chain.proceed()`,否则抛出运行时异常. (9认同)

小智 21

接受的答案中缺少的一件事是您需要指定协议和消息.如果您未指定将获得异常.看起来像这样:

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());
}
Run Code Online (Sandbox Code Playgroud)

  • 似乎最新的OkHttp库,也应该定义`body`.所以在我的情况下,添加`.body(ResponseBody.create(MediaType.get("text/html; charset = utf-8"),""))`解决了这个问题.感谢帮助. (10认同)