美文网首页
Exception:OkHttp Dispatcher

Exception:OkHttp Dispatcher

作者: OkCoco | 来源:发表于2017-12-05 12:58 被阅读0次
      项目中偶遇异常: image.png

      以下是异常代码片段:

      @Override
      public void onResponse(Response response) throws IOException {
             ...
             Log.d("", "onResponse: "+response.body().string());
             String responseContent = response.body().string();
              ...
      }
    

      异常定位到第二句代码,查看源码:

    将按照请求头Content-Type属性规定的编码格式进对Response行解码,默认为UTF-8
    public final String string() throws IOException {
        return new String(bytes(), charset().name());
      }
    
    public final byte[] bytes() throws IOException {
        long contentLength = contentLength();
        if (contentLength > Integer.MAX_VALUE) {
          throw new IOException("Cannot buffer entire body for content length: " + contentLength);
        }
    
        BufferedSource source = source();
        byte[] bytes;
        try {
          bytes = source.readByteArray();
        } finally {
          Util.closeQuietly(source);
        }
        if (contentLength != -1 && contentLength != bytes.length) {
          throw new IOException("Content-Length and stream length disagree");
        }
        return bytes;
      }
    

      OkHttp的底层封装了Okio,Source在Okio中相当于InputStream。finally语句中调用了 Util.closeQuietly(source);,相当于把输入流给关闭了。第二次调用string()方法,由上面日志可知,最终会执行到HttpConnection$FixedLengthSource的read()方法,真正实现如下:

    public long read(Buffer sink, long byteCount) throws IOException {
          if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
          if (closed) throw new IllegalStateException("closed");
          if (bytesRemaining == 0) return -1;
    
          long read = source.read(sink, Math.min(bytesRemaining, byteCount));
          if (read == -1) {
            unexpectedEndOfInput(); // The server didn't supply the promised content length.
            throw new ProtocolException("unexpected end of stream");
          }
    
          bytesRemaining -= read;
          if (bytesRemaining == 0) {
            endOfInput(true);
          }
          return read;
        }
    

    最终的异常为这句代码输出:
       if (closed) throw new IllegalStateException("closed");

    结论

      使用OkHttp时,不能接连调用两次Response的string()方法。

      在一些第三方库中,同样会有自己的一些细节上的实现,多踩坑,多学习。

    相关文章

      网友评论

          本文标题:Exception:OkHttp Dispatcher

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