美文网首页
OkHttp 报java.lang.IllegalStateEx

OkHttp 报java.lang.IllegalStateEx

作者: 皮皮铭 | 来源:发表于2019-09-25 17:33 被阅读0次

    原因是.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(),就会抛出异常
    纯属个人观点,如有错误欢迎指正!

    相关文章

      网友评论

          本文标题:OkHttp 报java.lang.IllegalStateEx

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