Exception:OkHttp Dispatcher

2017-12-05  本文已影响0人  OkCoco
  项目中偶遇异常: 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()方法。

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

上一篇下一篇

猜你喜欢

热点阅读