okhttp分析

okhttp用法
1、创建一个 OkhttpClient对象,使用了外观模式可以直接new 也可以Builder模式来创建OkhttpClient对象,在builder模式中可以添加拦截器和cookieJar等信息。
2、创建一个Request的请求对象,通过builder方法进行创建,然后添加请求相关的参数如请求方式,请求链接,请求头等信息。
3、通过okhttpClient对象调用newCall方法,并将request对象作为参数传入,返回一个call对象。
4、通过这个call对象调用excute方法或是enqueue方法。返回response对象。具体如下代码

   OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(null)
                .cookieJar(null)
                .build();
                
        Request request = new Request.Builder()
                .url("")
                .get()
                .addHeader("","")
                .build();

        Call call = okHttpClient.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });

okhttp执行流程

1、okhttpClient的newCall里面创建一个RealCall对象并请返回。
2、RealCall对象包含两个很重要的方法execute和equeue方法。
3、RealCall还有一个很重要的方法getResponseWithInterceptorChine方法新建拦截器链,把工作分解成可配置的分段流程。

先说一下execute的执行流程。
1、先会判断调用的请求是否执行过。如过执行过直接抛异常。
2、然后将当前的call对象存入dispatcher同步队列当中。
3、执行getResponseWithInterceptorChine()方法返回结果(这时得到来Response对象)。
4、将当前RealCall对象从dispatcher同步队列中移除。

enqueue执行的流程也是相似的。
1、首先会判断请求是否执行过,如果执行过直接抛异常。
2、会创建一个AsyncCall对象,添加到dispatcher异步执行队列当中去,如果正在执行的请求说小于64个,且请求同一主机小于5个则添加到执行队列当中,创建线程池来执行这个线程。否则进入异步等待队列。
3、AsyncCall中的execute方法中调用getResponseWithInterceptorChine()得到Response对象。
4、将正在执行的异步队列从dispatcher中移除,之后会检测等待队列,将满足条件的任务添加到执行队列中。

getResponseWithInterceptorChine方法
会将我们所有的拦截器组成一个链式结构首先是自己定义的拦截器,之后是Okhttp自定义的拦截器,如重试、桥接、缓存、链接、网络等,每一个拦截器都可以处理请求然后直接返回请求。

ApplicationInterceptor 自定义拦截器

BridgeInterceptor:主要对Request中的head设置默认值,比如Conntent-type、Connection、Cookie等。

CacheInterceptor:负责HTTP请求缓存处理。

ConnectInterceptor : 负责建立与服务器地址之间的连接,也就是TCP连接。

NetWorkInterceptor:自定义网络拦截器。

CallServerInterceptor:负责向服务器发送数据和从服务器里面获取数据。

对于在拦截器上添加header和建立TCP连接都是标准流程,可干预的空间不大,主要介绍CahceInterceptor。
NetWorkInterceptor 和ApplicationInterceptor 都是自定义拦截器,就是调用的层级不一样。NetWorkInterceptor 之前就已经处理了本地相关的拦截器,所以不一定会走到这个拦截器。而ApplicatinInterceptor在本地拦截之前就已经走了。

**说一下常用的拦截器CahceInterceptor
为什么要用到缓存。
1、减少服务端的压力。
2、读取本地数据更快。
3、在无网的情况下仍然有数据展现。

对于客户端来讲分为两种缓存:
1、强制缓存。
首先从缓存数据库里面找缓存,看缓存是否失效,如果没有失效直接返回缓存数据,如果失效则从服务器端获取新数据和缓存规则,对数据和缓存规则存入缓存数据库中。
2、对比缓存。
首先从缓存数据库里面拿到缓存数据的标识,请求服务器判断缓存标识数据是否有效,服务器返回未失效,如果有效直接从缓存里面读取数据,如果无效则返回数据和缓存规则,将数据和缓存规则存入缓存系统。
知道了缓存的概念,那何时使用强制缓存,何时使用对比缓存,如何确定强制缓存是否失效呢?
答案就是在请求头中。
强制缓存标志就是cache-control,可以设置强制缓存的时间(HTTP1.0用到expires ,在HTTP1.1 修改成cache-control)。
对比缓存
对比缓存有两套规则Last-modified/if-match-sence。和Etag/If-None-Match(优先级更高一些)
第一次请求数据的时候,服务器在响应头中返回一个Last-motified字段,告诉客户端最后一次修改的时间。客户端将数据和Last-motified 等信息存入缓存数据库中。
第二次请求时,从缓存里取出Last-motified的值,放入if-modified-sence字段中,作为请求头发到服务器,服务器进行判断如果文件修改的时间小于活等于if-modified-sence里面的值则说明缓存有效返回304直接从缓存里面获取数据。否则缓存无效直接返回新的数据和缓存规则个客户端,客户端在将新的数据和缓存规则存入缓存数据库中。
这就是HTTP的缓存策略,OKHTTP则是对这种思想的实现。
OKHTTP通过CacheStrategy和CacheIntercept结合实现了上面的所说的功能,在CacheStrategy里面通过请求头以及自身的缓存信息来确定缓存是否可用。在CacheIntercept里面返回,如果缓存可用则直接返回缓存,如果不可用则直接请求服务器看返回的响应头是否是304,如果是则直接用缓存里面数据,并更新缓存。如果不是304直接用网络数据,并判断是否有缓存文件以及是否可以缓存对数据进行缓存。
还有一个问题就是缓存如何存的问题,以及缓存数据满了之后如何清除的问题。
在OKHTTP中采用了DiskLruCache算法对缓存数据进行增删改查。

okhttp的底层实现
底层是socket连接来进行数据传输的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章