原因是.body.string()只能调用一次。再次调用就会抛if (closed) throw new IllegalStateException("closed");
分析:.body().string()
.body()创建一个ResponseBody对象
public @Nullable ResponseBody body() {
return body;
}
.string()
public final String string() throws IOException {
BufferedSource source = source();
try {
Charset charset = Util.bomAwareCharset(source, charset());
return source.readString(charset);
} finally {
Util.closeQuietly(source);
}
}
创建一个缓冲区source
Charset是Unicode字符和字节序列之间的命名映射
看readString()方法,调用了RealBufferedSource的readString()
@Override public String readString(Charset charset) throws IOException {
if (charset == null) throw new IllegalArgumentException("charset == null");
buffer.writeAll(source);
return buffer.readString(charset);
}
看writeAll()方法
@Override public long writeAll(Source source) throws IOException {
if (source == null) throw new IllegalArgumentException("source == null");
long totalBytesRead = 0;
for (long readCount; (readCount = source.read(this, Segment.SIZE)) != -1; ) {
totalBytesRead += readCount;
}
return totalBytesRead;
}
直接看for循环里面的source.read()方法,在RealBufferedSource类里面
@Override public long read(Buffer sink, long byteCount) throws IOException {
if (sink == null) throw new IllegalArgumentException("sink == null");
if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
if (closed) throw new IllegalStateException("closed");
if (buffer.size == 0) {
long read = source.read(buffer, Segment.SIZE);
if (read == -1) return -1;
}
long toRead = Math.min(byteCount, buffer.size);
return buffer.read(sink, toRead);
}
可以看到if (closed) throw new IllegalStateException("closed");这里抛出的异常
closed
@Override public void close() throws IOException {
if (closed) return;
closed = true;
source.close();
buffer.clear();
}
我们回到.string()方法,有个finally{}
public final String string() throws IOException {
BufferedSource source = source();
try {
Charset charset = Util.bomAwareCharset(source, charset());
return source.readString(charset);
} finally {
Util.closeQuietly(source);
}
}
进入closeQuietly()方法
public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (RuntimeException rethrown) {
throw rethrown;
} catch (Exception ignored) {
}
}
}
现在就很明显了,因为
finally {
Util.closeQuietly(source);
}
使的closed=true,所以在此调用string(),就会抛出异常
纯属个人观点,如有错误欢迎指正!
网友评论