Okhttp 框架使用和源码分析

近期学习了网络框架Rretrofit 和其依赖的底层Okhttp.
这里做一些整理。

首先网络框架的最根本的流程

1.request —–executor ———–Httpcall |
callback- —————————————|
所以分析是基于这三个基本模块进行分析的,收先是发起一个请求,然后交给执行器,执行器执行后,返回一个回调。
根据这个思路我们开始分析Okhttp
1.request
使用时我们通过 :

//创建一个Request
final Request request = new Request.Builder()
                .url("https://github.com/hongyangAndroid")
                .build();           
                这种方式创建一个Request 

2.通过:

     OkHttpClient okHttpClient = new OkHttpClient();
    OkHttpClient newClient = okHttpClient.newBuilder()
            .cache(provideCache())
            .connectTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .build();
        这种方式创建一个executor

3. 通过

new Callback()
        {
            @Override
            public void onFailure(Request request, IOException e)
            {
            }

            @Override
            public void onResponse(final Response response) throws IOException
            {
                    //String htmlStr =  response.body().string();
            }
        }

这些代码缠产生一个回调。
4. 通过 client.exqueue()这个方法进行异步调用

下面开始分析这些代码背后的原理。

首先上一张流程图:
这里写图片描述

Okhttp request

看源码可以知道
requeset 主要是对请求的URL header body 等信息进行的封装

    this.url = builder.url;
    this.method = builder.method;
    this.headers = builder.headers.build();
    this.body = builder.body;
    this.tag = builder.tag != null ? builder.tag : this;

这里不是重点,但是这个地方在后面Retrofit 进行了注解的更高级解耦.

okhttp中executer
最重要的环节就是和executer这部分 也就是OkhttpClient
阅读源码:
我们知道这个OkhttpClient 采用的是建造者模式进行的建造,

//new call
Call call = mOkHttpClient.newCall(request); 

当进行newCall这个方法之后就要执行这个Requset请求了 我们深入去看这个newCall 方法可以看到进入了一个realcall这个类,这个类就是核心类。
我们知道请求分为两种 同步和异步
通过阅读源码,同步:

 Response result = getResponseWithInterceptorChain(false);

通过getResponseWithInterceptorchain 方法返回最终的Response

异步:
是通过 disapcach 这个类中的exqueue方法执行的,可以发现这个disapach 构造器生成一个线程池,并还包含3个队列。
三个队列分别为

  • readyAsyncalls 等待队列
  • runningAsynacalls 运行时第异步队列
  • runningSyncall 运行时同步队列。

  • 而最终 执行的这个对象
client.dispatcher().enqueue(new AsyncCall(responseCallback, forWebSocket));

Asyncall 实际上是一个Runnble对象 ,放入该线程池中执行的run方法还是自己的exqueue方法。 可以看到最终执行的方法仍然是
getResponseWithInterceptorChain(false);
这个方法。

殊途同归。最终都走到了这个方法中,那么这个方法则真正的获取response 和 过滤器列表的方法了。着重看这个方法。
这可以看到,其中利用了 责任链模式,环环递进,最终返回Response。

依次说以下各个拦截器的作用
1. 重定向拦截器
2. BidgeInterCepter—–Gzip 压缩 和头数据的补全,负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应的 (返回代号等)。
3. CatchInterCepter—–取当初设置的缓存。catch中设置的缓存
4. connectIntercepTer –2.0 或1.0用不同的Httpstream
5. callServiceIntercepter
6. okio ————-里面用socket请求的

Okhttp中Response

真正的请求
内部是使用socket 方式请求的这里还没看到。

其中的缓存部分
而具体的缓存逻辑 OkHttp 内置封装了一个 Cache 类,它利用 DiskLruCache。按照 LRU 算法进行缓存淘汰。
如何设置缓存:

OkHttpClient okHttpClient = new OkHttpClient();
    OkHttpClient newClient = okHttpClient.newBuilder()
            .cache(provideCache())
            .build();

设置了缓存目录。

也可以自行实现 InternalCache 接口,在构造 OkHttpClient 时进行设置,这样就可以使用我们自定义的缓存策略了。

public class CacheInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        Response response1 = response.newBuilder()
                .removeHeader("Pragma")
                .removeHeader("Cache-Control")
                //cache for 30 days
                .header("Cache-Control", "max-age=" + 3600 * 24 * 30)
                .build();
        return response1;
    }
}

okhttp缓存设置参考文章:http://blog.youkuaiyun.com/copy_yuan/article/details/51524907

这就是Okhttp大致的请求流程。

可见Okhttp主要是在请求头 ,过滤器等方面进行的处理。

参考文章:
http://blog.piasy.com/2016/07/11/Understand-OkHttp/
http://www.open-open.com/lib/view/open1472216742720.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值