OKHttp

作者: 卡路fly | 来源:发表于2020-05-20 17:06 被阅读0次

    优点

    • 支持http请求,https请求。
    • 支持文件下载。
    • 使用的是HttpURLConnection,不要担心android版本的变换。(至少目前是都支持的)。
    • 支持get,post请求。
    • 基于Http的文件上传。
    • 加载图片。

    缺点

    • 比如callback回来是在线程里面, 不能刷新UI,需要我们手动处理。
    • 封装比较麻烦。

    基本使用

    直接 new OkHttpClient 之外,还可以使用内部工厂类 Builder 来设置 OkHttpClient。


    请求操作的起点从 OkHttpClient.newCall().enqueue() 方法开始:

    • newCall
      这个方法会返回一个 RealCall 类型的对象,通过它将网络请求操作添加到请求队列中。
    • RealCall.enqueue
      调用 Dispatcher 的入队方法,执行一个异步网络请求的操作。最终请求操作是委托给 Dispatcher的enqueue 方法内实现的。

    Dispatcher 是 OkHttpClient 的调度器,是一种门户模式。主要用来实现执行、取消异步请求操作。本质上是内部维护了一个线程池去执行异步操作,并且在 Dispatcher 内部根据一定的策略,保证最大并发个数、同一 host 主机允许执行请求的线程个数等。

    Dispatcher的enqueue 方法实际上就是使用线程池执行了一个 AsyncCall,而 AsyncCall 实现了 Runnable 接口,因此整个操作会在一个子线程(非 UI 线程)中执行。

    AsyncCall在 run 方法中执行了另一个 execute 方法,而真正获取请求结果的方法是在 getResponseWithInterceptorChain 方法中,其内部是一个拦截器的调用链。

    拦截器 作用
    BridgeInterceptor 主要对 Request 中的 Head 设置默认值,比如 Content-Type、Keep-Alive、Cookie 等
    CacheInterceptor 负责 HTTP 请求的缓存处理
    ConnectInterceptor 负责建立与服务器地址之间的连接,也就是 TCP 链接
    CallServerInterceptor 负责向服务器发送请求,并从服务器拿到远端数据结果

    在添加上述几个拦截器之前,会调用 client.interceptors 将开发人员设置的拦截器添加到列表当中。

    CacheInterceptor 缓存拦截器

    CacheInterceptor 主要做以下几件事情:

    a. 根据 Request 获取当前已有缓存的 Response(有可能为 null),并根据获取到的缓存 Response,创建 CacheStrategy 对象。
    b. 通过 CacheStrategy 判断当前缓存中的 Response 是否有效(比如是否过期),如果缓存 Response 可用则直接返回,否则调用 chain.proceed() 继续执行下一个拦截器,也就是发送网络请求从服务器获取远端 Response。
    c. 如果从服务器端成功获取 Response,再判断是否将此 Response 进行缓存操作。

    通过 Cache 实现缓存功能

    OkHttp 只是规范了一套缓存策略,但是具体使用何种方式将数据缓存到本地,以及如何从本地缓存中取出数据,都是由开发人员自己定义并实现,并通过 OkHttpClient.Builder 的 cache 方法设置。

    OkHttp 提供了一个默认的缓存类 Cache.java,我们可以在构建 OkHttpClient 时,直接使用 Cache 来实现缓存功能。只需要指定缓存的路径,以及最大可用空间即可。(实际上在 Cache 内部使用了 DiskLruCach 来实现具体的缓存功能,DiskLruCache 最终会以 journal 类型文件将需要缓存的数据保存在本地。如果感觉 OkHttp 自带的这套缓存策略太过复杂,我们可以设置使用 DiskLruCache 自己实现缓存机制。)


    CallServerInterceptor 详解

    是 OkHttp 中最后一个拦截器,也是 OkHttp 中最核心的网路请求部分

    intercept 方法主要分为 2 部分:

    • 向服务器端发送请求数据
    • 从服务端获取相应数据并构建 Response 对象。

    OkHttp 使用扩展

    CallServerInterceptor 中的 intercept 方法,在向服务端发送数据以及获取数据都是使用一个 Okio 的框架来实现的。Okio 是 Square 公司打造的另外一个轻量级 IO 库,它是 OkHttp 框架的基石。

    在构建 Response 时,需要调动 body() 方法传入一个 ResponseBody 对象。ResponseBody 内部封装了对请求结果的流读取操作。我们可以通过继承并扩展 ResponseBody 的方式获取网络请求的进度。

    a. 继承 ResponseBody

    b. 自定义 ProgressBarClient


    总结

    • 首先 OkHttp 内部是一个门户模式,所有的下发工作都是通过一个门户 Dispatcher 来进行分发。
    • 然后在网络请求阶段通过责任链模式,链式的调用各个拦截器的 intercept 方法。
      重点介绍了 2 个比较重要的拦截器:CacheInterceptor 和 CallServerInterceptor。它们分别用来做请求缓存和执行网络请求操作。

    网络请求库对比

    Volley

    Volley是Goole在2013年Google I/O大会上推出了一个新的网络通信框架,它是开源的。Volley 的特点:特别适合数据量小,通信频繁的网络操作。

    优点

    • 非常适合进行数据量不大,但通信频繁的网络操作。
    • 内部分装了异步线程。
    • 支持get,post网络请求。
    • 图片下载。
    • 可直接在主线程调用服务端并处理返回结果。
    • 可以取消请求,容易扩展,面向接口编程。

    缺点

    • 对大文件下载 Volley的表现非常糟糕。
    • 只支持http请求。
    • 在BasicNetwork中判断了statusCode(statusCode < 200 || statusCode > 299),如果合条件直
    • 图片加载性能一般。
    • 使用的是httpclient,HttpURLConnection。不过在android 6.0不支持httpclient了,如果想支持得添加org.apache.http.legacy.jar。

    相关文章

      网友评论

          本文标题:OKHttp

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