今天花了一天时间研究了下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 }
太晕了,来张图看看吧