okhtt使用及原理分析

*# 前言
http 介绍 使用 原理的学习


提示:以下是本篇文章正文内容,下面案例可供参考 @[TOC](文章目录)
# OkHttp介绍使用 由Square公司贡献的一个处理网络请求的开源项目,是目前Android使用最广泛的网络框架。从Android4.4开始HttpURLConnection的底层实现采用的是OkHttp。 [https://square.github.io/okhttp/](https://square.github.io/okhttp/)
  • 支持HTTP/2并允许对同一主机的所有请求共享一个套接字
  • 通过连接池,减少了请求延迟
  • 默认通过GZip压缩数据响应缓存,避免了重复请求的网络
  • 请求失败自动重试主机的其他ip,自动重定向

一、使用方法

get请求

        OkHttpClient client = new OkHttpClient();
        //创建一个Request
        Request request = new Request.Builder()
                .get()
                .url(url)
                .build();
        //通过client发起请求
        client.newCall(request).enqueue(new Callback() {//异步execute
            @Override
            public void onFailure(Call call, IOException e) {
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                // String str = response.body().string();
                }
    
            }
        });
        

post请求

        OkHttpClient client = new OkHttpClient();
        RequestBody body = new FormBody.Builder().add("username","xiaoyi").build();
        Request request = new Request.Builder()
                .post(body)
                .url(url).
                build();
        client.newCall(request).enqueue(new Callback() {...}); //异步execute
        

调用流程

OkHttp请求过程中最少只需要接触OkHttpClient、Request、Call、Response,但是框架内部进行大量的逻辑处理。 所有的逻辑大部分集中在拦截器中,但是在进入拦截器之前还需要依靠分发器来调配请求任务。

  • 分发器:内部维护队列与线程池,完成请求调配;
  • 拦截器:五大默认拦截器完成整个请求过程。
    在这里插入图片描述

分发器:异步请求工作流程

在这里插入图片描述
Q: 如何决定将请求放入ready还是running?
A: 如果当前正在请求数不小于64放入ready;如果小于64,但是已经存在同一域名主机的请求5个放入ready!
Q: 从running移动ready的条件是什么?
A: 每个请求执行完成就会从running移除,同时进行第一步相同逻辑的判断,决定是否移动!
Q: 分发器线程池的工作行为?
A:无等待,最大并发

线程池(由于okhttp 分发器用无等待最大并发线程池 所以先看下线程池的工作原理)

在这里插入图片描述
当一个任务通过execute(Runnable)方法添加到线程池时:
线程数量小于corePoolSize,新建线程(核心)来处理被添加的任务;

线程数量大于等于 corePoolSize,存在空闲线程,使用空闲线程执行新任务;

线程数量大于等于 corePoolSize,不存在空闲线程,新任务被添加到等待队列,添加成功则等待空闲线程,添加失败:
线程数量小于maximumPoolSize,新建线程执行新任务;
线程数量等于maximumPoolSize,拒绝此任务

拦截器相关

在请求需要执行时,通过 getResponseWithInterceptorChain 获得请求的结果: Response

    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);
     }
             

拦截器执行流程

在这里插入图片描述
拦截器责任链 请求任务交给Chain即可

在这里插入图片描述

okhttp中的五大拦截器

  1. 重试拦截器在交出(交给下一个拦截器)之前,负责判断用户是否取消了请求;在获得了结果之后,会根据响应码判断是否需要重定
    向,如果满足条件那么就会重启执行所有拦截器。
  2. 桥接拦截器在交出之前,负责将HTTP协议必备的请求头加入其中(如:Host)并添加一些默认的行为(如:GZIP压缩);在获得了结果后,调用保存cookie接口并解析GZIP数据。
  3. 缓存拦截器顾名思义,交出之前读取并判断是否使用缓存;获得结果后判断是否缓存。
  4. 连接拦截器在交出之前,负责找到或者新建一个连接,并获得对应的socket流;在获得结果后不进行额外的处理。
  5. 请求服务器拦截器进行真正的与服务器的通信,向服务器发送数据,解析读取的响应数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值