为什么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
网友评论