今天花了一天时间研究了下OkHttp3的内部原理,记录在此处以便后期查阅

我们先来看下基本的使用方式:

 1  public  void sendHttpRequest(String url,Callback callback){
 2         OkHttpClient client=new OkHttpClient();
 3         Request request=new Request.Builder().url(url).build();
 4         client.newCall(request).enqueue(callback); //异步执行
 5         try {
 6             client.newCall(request).execute();//同步执行
 7         } catch (IOException e) {
 8             e.printStackTrace();
 9         }
10     }

接下来的分析就以异步执行开始

1  @Override
2 public Call newCall(Request request) {
3     return new RealCall(this, request, false /* for web socket */);
4 }
1   RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
2     this.client = client;
3     this.originalRequest = originalRequest;
4     this.forWebSocket = forWebSocket;
5     this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
6   }

  RealCall的enqueue()方法

1   @Override public void enqueue(Callback responseCallback) {
2     synchronized (this) {
3       if (executed) throw new IllegalStateException("Already Executed");
4       executed = true;
5     }
6     captureCallStackTrace();
7     client.dispatcher().enqueue(new AsyncCall(responseCallback));
8   }

  

1  synchronized void enqueue(AsyncCall call) {
2     if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {//同时发起的请求不能超过最大请求数,如果超过了,就放入readyAsyncCalls队列
3       runningAsyncCalls.add(call);
4       executorService().execute(call);
5     } else {
6       readyAsyncCalls.add(call);
7     }
8   }

  线程池

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

  执行AsyncCall 的run方法 ,在父类 NamedRunnable 中

 @Override public final void run() {
    String oldName = Thread.currentThread().getName();
    Thread.currentThread().setName(name);
    try {
      execute();
    } finally {
      Thread.currentThread().setName(oldName);
    }
  }

  protected abstract void execute();//由子类实现
 1   @Override protected void execute() {
 2       boolean signalledCallback = false;
 3       try {
 4         Response response = getResponseWithInterceptorChain();//重点查看
 5         if (retryAndFollowUpInterceptor.isCanceled()) {
 6           signalledCallback = true;
 7           responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
 8         } else {
 9           signalledCallback = true;
10           responseCallback.onResponse(RealCall.this, response);
11         }
12       } catch (IOException e) {
13         if (signalledCallback) {
14           // Do not signal the callback twice!
15           Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
16         } else {
17           responseCallback.onFailure(RealCall.this, e);
18         }
19       } finally {
20         client.dispatcher().finished(this);
21       }
22     }

  现在我们进入 getResponseWithInterceptorChain() 方法查看

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);
    return chain.proceed(originalRequest); 
  }
 1   public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
 2       Connection connection) throws IOException {
 3  //........
 4     RealInterceptorChain next = new RealInterceptorChain(
 5         interceptors, streamAllocation, httpCodec, connection, index + 1, request);
 6     Interceptor interceptor = interceptors.get(index);
 7     Response response = interceptor.intercept(next); //拦截器中都会调用 chain.proceed(request)来获取response,产生递归,依次调用各个拦截器的intercept方法
 8 
 9  //.........
10 
11     return response;
12   }

  其他拦截器就不看了,我们来看看比较重要的缓存拦截器

  

 1   @Override public Response intercept(Chain chain) throws IOException {
 2     Response cacheCandidate = cache != null
 3         ? cache.get(chain.request())
 4         : null;//查看是否有缓存
 5 
 6     CacheStrategy strategy = new CacheStrategy.Factory(now, chain.request(), cacheCandidate).get();//根据缓存响应头返回的一些信息来制定缓存策略,是从缓存取还是从网络上取
 7     Request networkRequest = strategy.networkRequest;
 8     Response cacheResponse = strategy.cacheResponse;
 9 
10    //..............
11 
12     // If we're forbidden from using the network and the cache is insufficient, fail. 禁止使用网络并且缓存也是空的,请求失败
13     if (networkRequest == null && cacheResponse == null) {
14       return new Response.Builder()
15           .request(chain.request())
16           .protocol(Protocol.HTTP_1_1)
17           .code(504)
18           .message("Unsatisfiable Request (only-if-cached)")
19           .body(Util.EMPTY_RESPONSE)
20           .sentRequestAtMillis(-1L)
21           .receivedResponseAtMillis(System.currentTimeMillis())
22           .build();
23     }
24 
25     // If we don't need the network, we're done. 如果不需要网络,直接返回缓存
26     if (networkRequest == null) {
27       return cacheResponse.newBuilder()
28           .cacheResponse(stripBody(cacheResponse))
29           .build();
30     }
31 
32     Response networkResponse = null;
33     try {
34       networkResponse = chain.proceed(networkRequest);
35     } finally {
36       // If we're crashing on I/O or otherwise, don't leak the cache body.
37       if (networkResponse == null && cacheCandidate != null) {
38         closeQuietly(cacheCandidate.body());
39       }
40     }
41 
42     // If we have a cache response too, then we're doing a conditional get.
43     if (cacheResponse != null) {
44       if (networkResponse.code() == HTTP_NOT_MODIFIED) {
45         Response response = cacheResponse.newBuilder()
46             .headers(combine(cacheResponse.headers(), networkResponse.headers()))
47             .sentRequestAtMillis(networkResponse.sentRequestAtMillis())
48             .receivedResponseAtMillis(networkResponse.receivedResponseAtMillis())
49             .cacheResponse(stripBody(cacheResponse))
50             .networkResponse(stripBody(networkResponse))
51             .build();
52         networkResponse.body().close();
53 
54         // Update the cache after combining headers but before stripping the
55         // Content-Encoding header (as performed by initContentStream()).
56         cache.update(cacheResponse, response); //更新缓存
57         return response;
58       } else {
59         closeQuietly(cacheResponse.body());
60       }
61     }
62 
63     Response response = networkResponse.newBuilder()
64         .cacheResponse(stripBody(cacheResponse))
65         .networkResponse(stripBody(networkResponse))
66         .build();
67 
68     if (HttpHeaders.hasBody(response)) {
69       CacheRequest cacheRequest = maybeCache(response, networkResponse.request(), cache);
70       response = cacheWritingResponse(cacheRequest, response);
71     }
72 
73     return response;
74   }

太晕了,来张图看看吧

posted on 2017-02-07 20:26  向着大牛奋斗  阅读(1040)  评论(0编辑  收藏  举报