当前位置: 代码迷 >> 综合 >> okhttp 网络分析(一)
  详细解决方案

okhttp 网络分析(一)

热度:90   发布时间:2023-12-13 04:58:40.0

简介:这篇主要分析网络的调用流程

1,简单的okhttp的调用代码

//初始化OkHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(5,TimeUnit.SECONDS)
                .readTimeout(5,TimeUnit.SECONDS);
                //.cache(new Cache(file.getAbsoluteFile(),maxCacheSize));
mOkHttpClient = builder.build();

//创建request
final Request request = new Request.Builder().url(url).build();
//创建Call
Call call = mOkHttpClient.newCall(request);

//异步调用:添加call 到队列中
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        sendFailedCallBack(call,callBack,e);
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        sendSuccessCallBack(response.body().string(),callBack);
    }
    });

//同步调用
try {
    call.execute();
} catch (IOException e) {
    e.printStackTrace();
}

2,从Call call = mOkHttpClient.newCall(request)开始

 @Override

public Call newCall(Request request) {

  // 具体call的实现是RealCall 
    return RealCall.newRealCall(this, request, false);
  }

3,call.enqueue其实调用的是RealCall 中的enqueue

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

   // 添加到分发中的队列去,将用户的回调封装到AsyncCall中
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }

查看dispathcher的enqueue的方法

 synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);

     //线程池去执行
      executorService().execute(call);

    } else {
      readyAsyncCalls.add(call);
    }
  }

到此提交到线程池中执行AsyncCall任务;

下面查看下AsyncCall中怎么调用的

@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 {eventListener.callFailed(RealCall.this, e);responseCallback.onFailure(RealCall.this, e);}} finally {//释放请求client.dispatcher().finished(this);}
}

查看具体的网络请求的代码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));//通过RealInterceptorChain中的proceed()来循环调用各个拦截器来实现网络的请求Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,originalRequest, this, eventListener, client.connectTimeoutMillis(),client.readTimeoutMillis(), client.writeTimeoutMillis());return chain.proceed(originalRequest);
}

大致的网络调用就是这样的,下一节具体分析拦截器的具体调用

  相关解决方案