开原框架OKHTTP

由Square公司贡献的一个处理网络请求的开源项目,是目前Android使用最广泛的网络框架。从Android4.4开始 HttpURLConnection的底层实现采用的是OkHttp。

 

特点:

1、支持HTPP/2并允许对同一主机的所有请求共享套接字

2、如果非HTTP/2,则通过连接池减少请求延迟

3、默认请求GZip压缩数据

4、响应缓存,避免了重复请求的网络

使用方法:

private static void get(String url,OkHttpClient client) throws IOException {
        Request request = new Request.Builder()
                .url(url).build();
        //同步请求
        Call call = client.newCall(request);
        Response response = call.execute();
        //获取响应
        ResponseBody body = response.body();
        System.out.println(body.toString());
    }


    private static void post(String url,OkHttpClient client){
        RequestBody requestBody = new FormBody.Builder().add("name","111")
                .add("age","11").build();
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        // 执行异步请求
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                System.out.println(response.toString());
            }
        });

    }

OkHttp请求过程中最少只需要接触OkHttpClient、Request、Call、 Response,但是框架内部进行大量的逻辑处理。而且通过HttpClient可以看出是用的Builder设计模式。

分发器:

1、同步分发

        同步分发只有一个running的同步队列,分发器只记录请求,用于判断IdleRunnable是否需要执行

2、异步请求,有一个ready执行的队列和一个running队列,这两个队列是如何处理工作的呢

 1)对于符合条件的call是什么条件呢,我们应该是放入running队列还是ready队列?

        . running队列中任务不能大于64

        . 同一域名主机的请求不能大于5

        满足上面两个条件就放入running队列,否则放入ready队列。

2)从ready队列移动到running队列

        遍历ready队列,假如1)的两个条件都满足,则从ready中移出call,添加到running队列

3)分发器的线程

        这个线程池有点意思,我们看参数:

public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }

        核心线程数=0、最大线程数=Integer.MAX_VALUE、任务队列使用的是SynchronousQueue队列 ,这是一个不存储元素的阻塞队列,就这个保证了任务执行无需等待,符合我们的网络请求场景。

拦截器:

在请求需要执行时,通过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);
  }

首先,拦截器采用的是责任链设计模式

客户只需要将请求发送到责任链上即可,无须关心请求的处理细节个请求传递;这样责任链就将请求的发送者和处理者解耦了。 

 重试重定向拦截器:

重定向: followUpRequest(response, streamAllocation.route())重新返回一个经过重定向的Request。并且重定向的次数不能大于20次

 

 桥接拦截器:

其实就是补全请求头

 缓存拦截器:

缓存规则:http的缓存我们可以按照行为将它们分为强缓存、协商缓存

        1、强缓存:表示浏览器不会将请求发送给服务器,直接从缓存中取,利用http的返回头中的Expires或者Cache-Control两个字段来控制,用来表示资源的缓存时间。

        2、协商缓存:表示浏览器会将请求发送到服务器,服务器告诉浏览器可以从缓存中获取响应。响应码返回304。

缓存策略:

        拦截器通过CacheStrategy判断使用缓存或发起网络请求。此对象中的networkRequest与cacheResponse分别代表需要发起请求或者直接使用缓存。

networkRequestcacheResponse说明
NullNot Null直接使用缓存
Not NullNull向服务器发起请求
NullNull要求使用缓存,但是没有缓存。直接gg,okhttp直接返回504
Not NullNot Null发起请求,若得到响应为304(无修改),则更新缓存响应并返回

即:networkRequest存在则优先发起网络请求,否则使用cacheResponse缓存,若都不存在则请求失败!

连接拦截器:

请求服务拦截器: 

Expect:100-continue

        一般出现于上传大容量请求体或者需要验证。代表了先询问服务器是否原因接 收发送请求体数据, 

        OkHttp的做法: 

        如果服务器允许则返回100,客户端继续发送请求体; 

        如果服务器不允许则直接返回给用户。 

        同时服务器也可能会忽略此请求头,一直无法读取应答,此时抛出超时异常

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值