OKHttp請求超時無效問題記錄

發(fā)現(xiàn)問題

在項目開發(fā)中發(fā)現(xiàn),發(fā)起網(wǎng)絡請求是會一直顯示Loading。但是我們在okhttp初始化的時候已經(jīng)設置的網(wǎng)絡請求超時時間為30s。為什么會出現(xiàn)這種情況 WTF!

解決問題

通過斷點調(diào)試發(fā)現(xiàn),在AsyTask中發(fā)起網(wǎng)絡請求的位置停住了。導致線程一直無法中斷。通過一步一步斷點發(fā)現(xiàn)。
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循環(huán)
        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");
    }

原來一直在執(zhí)行while循環(huán),Okhttp在網(wǎng)絡請示出現(xiàn)錯誤時會重新發(fā)送請求,最終會不斷執(zhí)行

 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

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容