OKHttp3 use principle and source code analysis

Posted by storyteller on Fri, 17 Sep 2021 19:54:11 +0200

brief introduction

OKHttp3 is a java and Android network SDK that supports http1 and http2 network protocols. OKHttp relies on OKIO.

component

1,OKHttpClient
The OKHttpClient class combines multiple objects, implements the Call.Factory interface, provides a newCall method, and returns realcall (the specific implementation class of call). It is best to create a single instance using OKHttpClient, because each client has its own connection pool and thread pool. Reusing these connection pools and thread pools can reduce latency and save memory.

/**
   * Prepares the {@code request} to be executed at some point in the future.
   */
  @Override 
  public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false /* for web socket */);
  }

2,Dispatcher
It can be understood as a policy that continuously fetches requests from the RequestQueue when calling newcall;
Call the synchronization method and directly return the Response. The code is as follows:

@Override 
public Response execute() throws IOException {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    try {
      client.dispatcher().executed(this);
      Response result = getResponseWithInterceptorChain();
      if (result == null) throw new IOException("Canceled");
      return result;
    } catch (IOException e) {
      eventListener.callFailed(this, e);
      throw e;
    } finally {
      client.dispatcher().finished(this);
    }
  }

Call the asynchronous method to add the current request to the request queue and return the result through callback. The code is as follows:

@Override 
public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

When calling.enqueue, that is, dispatcher.enqueue is called. It is worth noting that in the dispatcher.enqueue method, if the current number of asynchronous request queues is less than the maximum number of 64 and the number of requests from the same host is less than 5, the request is added to the running queue and handed over to the thread pool for resolution. Whether to put it into the waiting queue is as follows:

synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);
      executorService().execute(call);
    } else {
      readyAsyncCalls.add(call);
    }
  }

3,interceptor
It is the OKHttp core class, which unifies the network request, cache, compression and other functions. Each function is an interceptor, and then connected into an interceptor.chain to complete a network request. The code is as follows:

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);
  }

flow chart

summary

1. Create a call through OKHttpClient to send synchronous or asynchronous requests;
2. OKHttp uniformly manages all realcall s (specific implementation classes of calls) through the dispatcher and processes requests;
3. Both execute() and enqueue() will eventually call getResponseWithInterceptorChain() of realcall to get the results from the interceptor;
4. In the interceptor, retryandfollowupinterceptor, bridgeinterceptor, cacheinterceptor, connectinterceptor and callserverinterceptor are called successively through the responsibility chain mode to process the requests and obtain the returned results.

Topics: Java Android OkHttp