网络 OkHttp 面试

2020-04-15  本文已影响0人  Android_冯星

1. OkHttp对于网络请求都有哪些优化

2. OkHttp框架中都用到了哪些设计模式

3. 为什么response.body().string() 只能调用一次

我们可能习惯在获取到Response对象后,先response.body().string()打印一遍log,再进行数据解析,却发现第二次直接抛异常,其实直接跟源码进去看就发现,通过source拿到字节流以后,直接给closeQuietly悄悄关闭了,这样第二次再去通过source读取就直接流已关闭的异常了。

public final String string() throws IOException {
    BufferedSource source = source();
    try {
      Charset charset = Util.bomAwareCharset(source, charset());
      return source.readString(charset);
    } finally {
      //这里讲resource给悄悄close了
      Util.closeQuietly(source);
    }
  }

4. 如何实现网络请求

OkHttp3的最底层是Socket,而不是URLConnection,它通过Platform的Class.forName()反射获得当前Runtime使用的socket库。

5. 断点续传

step 1:判断检查本地是否有下载文件,若存在,则获取已下载的文件大小 downloadLength,若不存在,那么本地已下载文件的长度为 0
step 2:获取将要下载的文件总大小(HTTP 响应头部的 content-Length)
step 3:比对已下载文件大小和将要下载的文件总大小(contentLength),判断要下载的长度
step 4:再即将发起下载请求的 HTTP 头部中添加即将下载的文件大小范围(Range: bytes = downloadLength - contentLength)

6. Dispatcher

OkHttp设置了默认的最大并发请求量 maxRequests = 64 和单个host支持的最大并发量 maxRequestsPerHost = 5。

7. RetryAndFollowUpInterceptor

负责失败自动重连和必要的重定向

8. BridgeInterceptor

9. CacheInterceptor

10. ConnectInterceptor

1.尝试当前连接是否可以复用。
2.尝试连接池中找可以复用的连接
3.切换路由,继续在连接中尝试找可以复用的连接
4.以上都没有则new一个新的。
5.新的连接放入连接池
5.建立连接,开始握手

11. CallServerInterceptor

1.先写入请求Header
2.如果请求头的Expect: 100-continue时,只发送请求头,执行3,不然执行4
3.根据后台返回的结果判断是否继续请求流程
4.写入请求体,完成请求
5.得到响应头,构建初步响应
6.构建响应体,完成最终响应
7.返回响应

12. addInterceptor与addNetworkInterceptor的区别

二者通常的叫法为应用拦截器和网络拦截器,从整个责任链路来看,应用拦截器是最先执行的拦截器,也就是用户自己设置request属性后的原始请求,而网络拦截器位于ConnectInterceptor和CallServerInterceptor之间,此时网络链路已经准备好,只等待发送请求数据。

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
        originalRequest, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    return chain.proceed(originalRequest);
  }

总结

image.png

https://juejin.im/post/5e59be00f265da57455b4709

https://www.jianshu.com/p/b32d13655be7

上一篇下一篇

猜你喜欢

热点阅读