为什么okhttp的response.body().string

2019-11-13  本文已影响0人  NullPoint3Exce

为什么okhttp的response.body().string 只调用一次?
相信大家在使用okhttp的时候,都遇到过这个问题。why?

  public final String string() throws IOException {
  //缓存对象
    BufferedSource source = source();
    try {
      Charset charset = Util.bomAwareCharset(source, charset());
      // 把数据写入到缓存对象里。
      return source.readString(charset);
    } finally {
      Util.closeQuietly(source);
    }
  }

//然后看下这个方法
 Util.closeQuietly(source);

  /**
   * Closes {@code closeable}, ignoring any checked exceptions. Does nothing if {@code closeable} is
   * null.
   */
  public static void closeQuietly(Closeable closeable) {
    if (closeable != null) {
      try {
    //最终会把closeable对象给关闭,closeable其实是BufferedSource 对象,但是BufferedSouce是个接口,所以去找它的实现类,也就是RealBufferedSource,看代码。
        closeable.close();
      } catch (RuntimeException rethrown) {
        throw rethrown;
      } catch (Exception ignored) {
      }
    }
  }


RealBufferedSource的close方法

  @Override public void close() throws IOException {
    if (closed) return;
    closed = true; 此处状态的改变
    source.close();
    buffer.clear();
  }

再回到顶部string()方法里,去找Util.bomAwareCharset(source, charset());

  public static Charset bomAwareCharset(BufferedSource source, Charset charset) throws IOException {
    if (source.rangeEquals(0, UTF_8_BOM)) {
      source.skip(UTF_8_BOM.size());
      return UTF_8;
    }
   ....省略
    return charset;
  }


// 该方法是接口的抽象方法,去找实现类。也就是RealBufferedSource
  boolean rangeEquals(long offset, ByteString bytes) throws IOException;


//继续跟进


  @Override public boolean rangeEquals(long offset, ByteString bytes) throws IOException {
    return rangeEquals(offset, bytes, 0, bytes.size());
  }


  @Override
  public boolean rangeEquals(long offset, ByteString bytes, int bytesOffset, int byteCount)
      throws IOException {
//进行变量的判断,如果关闭了,抛出异常。
    if (closed) throw new IllegalStateException("closed");

   。。。。省略
    return true;
  }

因此报错如图

ddd
上一篇下一篇

猜你喜欢

热点阅读