美文网首页
OKHttp请求超时无效问题记录

OKHttp请求超时无效问题记录

作者: 1琥珀川1 | 来源:发表于2017-07-03 23:24 被阅读3500次

发现问题

在项目开发中发现,发起网络请求是会一直显示Loading。但是我们在okhttp初始化的时候已经设置的网络请求超时时间为30s。为什么会出现这种情况 WTF!

解决问题

通过断点调试发现,在AsyTask中发起网络请求的位置停住了。导致线程一直无法中断。通过一步一步断点发现。
Code

 public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        this.streamAllocation = new StreamAllocation(this.client.connectionPool(), this.createAddress(request.url()));
        int followUpCount = 0;
        Response priorResponse = null;
       //while循环
        while(!this.canceled) {
            Response response = null;
            boolean releaseConnection = true;

            try {
                response = ((RealInterceptorChain)chain).proceed(request, this.streamAllocation, (HttpStream)null, (Connection)null);
                releaseConnection = false;
            } catch (RouteException var12) {
                if(!this.recover(var12.getLastConnectException(), true, request)) {
                    throw var12.getLastConnectException();
                }

                releaseConnection = false;
                continue;
            } catch (IOException var13) {
                if(!this.recover(var13, false, request)) {
                    throw var13;
                }

                releaseConnection = false;
                continue;
            } finally {
                if(releaseConnection) {
                    this.streamAllocation.streamFailed((IOException)null);
                    this.streamAllocation.release();
                }

            }

            if(priorResponse != null) {
                response = response.newBuilder().priorResponse(priorResponse.newBuilder().body((ResponseBody)null).build()).build();
            }

            Request followUp = this.followUpRequest(response);
            if(followUp == null) {
                if(!this.forWebSocket) {
                    this.streamAllocation.release();
                }

                return response;
            }

            Util.closeQuietly(response.body());
            ++followUpCount;
            if(followUpCount > 20) {
                this.streamAllocation.release();
                throw new ProtocolException("Too many follow-up requests: " + followUpCount);
            }

            if(followUp.body() instanceof UnrepeatableRequestBody) {
                throw new HttpRetryException("Cannot retry streamed HTTP body", response.code());
            }

            if(!this.sameConnection(response, followUp.url())) {
                this.streamAllocation.release();
                this.streamAllocation = new StreamAllocation(this.client.connectionPool(), this.createAddress(followUp.url()));
            } else if(this.streamAllocation.stream() != null) {
                throw new IllegalStateException("Closing the body of " + response + " didn\'t close its backing stream. Bad interceptor?");
            }

            request = followUp;
            priorResponse = response;
        }

        this.streamAllocation.release();
        throw new IOException("Canceled");
    }

原来一直在执行while循环,Okhttp在网络请示出现错误时会重新发送请求,最终会不断执行

 catch (IOException var13) {
                if(!this.recover(var13, false, request)) {
                    throw var13;
                }

                releaseConnection = false;
                continue;
            } 

可以看到这个方法recover只要将他返回false就可以了

 private boolean recover(IOException e, boolean routeException, Request userRequest) {
        this.streamAllocation.streamFailed(e);
        return !this.client.retryOnConnectionFailure()?false:(!routeException && userRequest.body() instanceof UnrepeatableRequestBody?false:(!this.isRecoverable(e, routeException)?false:this.streamAllocation.hasMoreRoutes()));
    }

既然retryOnConnectionFailure返回false
终上所述我们只需在Okhttp初始化的时候添加如下代码即可

  sClient = builder.retryOnConnectionFailure(false).build();

更新

该问题 在3.4.2版本已处理
https://github.com/square/okhttp/issues/2756

相关文章

网友评论

      本文标题:OKHttp请求超时无效问题记录

      本文链接:https://www.haomeiwen.com/subject/kttthxtx.html