美文网首页Android开发经验谈
(一)okhttp源码分析——入门篇

(一)okhttp源码分析——入门篇

作者: Raven | 来源:发表于2020-04-22 16:44 被阅读0次

引言

本篇文章为okhttp源码解析系列的第一篇,以日常调用API为主线,进行剖析,梳理流程。不会深入到代码细节方面,为各位看官留下个大致的印象,不至于陷入细节的思维旋涡中。

同步阻塞调用

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();

OkHttpClient构造时,会通过public方法Builder初始化数据。Request的实例化通过其静态内部类Builder实现。client.newCall(),实例化call的子类RealCall,由realcall实现execute动作。execute调用getResponseWithInterceptorChain,这个方法中添加了很多的拦截器。我们只关注最后一个拦截器CallServerInterceptor。

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

RealInterceptorChain.proceed中不断递归调用所有的拦截器,当轮训到最后一个拦截器CallServerInterceptor时,才停止递归,返回Response。

RealInterceptorChain next = new RealInterceptorChain(
        interceptors, streamAllocation, httpCodec, connection, index + 1, request);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);

具有回调的异步调用

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
            @Override
            public void onFailure(final Request request, final IOException e) {
            }

            @Override
            public void onResponse(Response response) throws IOException {
            }
        });

异步的话就不是execute而是enqueue,从api名字就能猜出,应该是把callback插入到某个队列中,当这个队列轮训到该callback时,就会execute该request,最后响应callback。让我们一起来看看是否如此吧!

void enqueue(Callback responseCallback, boolean forWebSocket) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

这里将callback包装成AsyncCall。当前正在运行AsyncCall数量小于64,同一host下的AsyncCall数量小于5,就会直接插入了线程池ThreadPoolExecutor中并加入运行队列中。该线程池没有核心线程,但最大线程数为Integer.MAX_VALUE,会立刻启动一个非核心线程来执行任务。若不满足上述条件,就会进入等待队列中,当运行队列中AsyncCall.execute后,会执行Dispatcher.finished方法,试图将等待队列中的AsyncCall加入运行队列中,加入线程池。

synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);
      executorService().execute(call);
    } else {
      readyAsyncCalls.add(call);
    }
  }
  
public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }

AsyncCall.execute()获取response的方法就和同步阻塞调用一致了,这里就不再赘述。

@Override protected void execute() {
      boolean signalledCallback = false;
      try {
        Response response = getResponseWithInterceptorChain();
        if (retryAndFollowUpInterceptor.isCanceled()) {
          signalledCallback = true;
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          signalledCallback = true;
          responseCallback.onResponse(RealCall.this, response);
        }
      } catch (IOException e) {
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }

相关文章

网友评论

    本文标题:(一)okhttp源码分析——入门篇

    本文链接:https://www.haomeiwen.com/subject/aicwihtx.html