OkHttpCall创建源码解析

138 阅读2分钟

Call

package retrofit2;

import java.io.IOException;
import okhttp3.Request;

public interface Call<T> extends Cloneable {
 
  //同步执行请求
  Response<T> execute() throws IOException;
  //异步执行请求,callback 用于回调
  void enqueue(Callback<T> callback);
  //是否执行过
  boolean isExecuted();
  //取消请求
  void cancel();
  //是否取消了
  boolean isCanceled();
  //克隆一条请求 
  Call<T> clone();
  //获取原始的request
  Request request();
    
}

成员变量

final class OkHttpCall<T> implements Call<T> {
  (1)里面包含了网络请求的参数等各种信息
  private final ServiceMethod<T, ?> serviceMethod;
 (2)用户传递的方法请求参数
  private final Object[] args;
 (3)是否取消请求
  private volatile boolean canceled;

 (4)okhttp的Call,执行网络请求的  
  // All guarded by this.
  private okhttp3.Call rawCall;
 (5)异常
 private Throwable creationFailure; // Either a RuntimeException or IOException.6)是否执行过
  private boolean executed;
}

构造方法

1)传入serviceMethod和请求参数
OkHttpCall(ServiceMethod<T, ?> serviceMethod, Object[] args) {
  this.serviceMethod = serviceMethod;
  this.args = args;
}

同步方法

@Override public Response<T> execute() throws IOException {
  okhttp3.Call call;

  synchronized (this) {
    if (executed) throw new IllegalStateException("Already executed.");
    executed = true;

    if (creationFailure != null) {
      if (creationFailure instanceof IOException) {
        throw (IOException) creationFailure;
      } else {
        throw (RuntimeException) creationFailure;
      }
    }

    call = rawCall;
    if (call == null) {
      try {
       (1)重点关注这里
        call = rawCall = createRawCall();
      } catch (IOException | RuntimeException e) {
        creationFailure = e;
        throw e;
      }
    }
  }

  if (canceled) {
    call.cancel();
  }

  return parseResponse(call.execute());
}
private okhttp3.Call createRawCall() throws IOException {
 (1)根据用户传入的参数构造出RequestRequest request = serviceMethod.toRequest(args);
  (2)构造Okhttp Call
  okhttp3.Call call = serviceMethod.callFactory.newCall(request);
  if (call == null) {
    throw new NullPointerException("Call.Factory returned null.");
  }
  return call;
}

Request toRequest(Object... args) throws IOException {
  RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl, headers,
      contentType, hasBody, isFormEncoded, isMultipart);

  @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.1)接口方法里面的形参
  ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;

  int argumentCount = args != null ? args.length : 0;
  if (argumentCount != handlers.length) {
    throw new IllegalArgumentException("Argument count (" + argumentCount
        + ") doesn't match expected count (" + handlers.length + ")");
  }

  for (int p = 0; p < argumentCount; p++) {
    handlers[p].apply(requestBuilder, args[p]);
  }

  return requestBuilder.build();
}

异步方法

@Override public void enqueue(final Callback<T> callback) {
  if (callback == null) throw new NullPointerException("callback == null");

  okhttp3.Call call;
  Throwable failure;

  synchronized (this) {
    if (executed) throw new IllegalStateException("Already executed.");
    executed = true;

    call = rawCall;
    failure = creationFailure;
    if (call == null && failure == null) {
      try {
       (1)创建真正的OkhttpCall
        call = rawCall = createRawCall();
      } catch (Throwable t) {
        failure = creationFailure = t;
      }
    }
  }

  if (failure != null) {
    callback.onFailure(this, failure);
    return;
  }

  if (canceled) {
    call.cancel();
  }

  call.enqueue(new okhttp3.Callback() {
    @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
        throws IOException {
      Response<T> response;
      try {
        response = parseResponse(rawResponse);
      } catch (Throwable e) {
        callFailure(e);
        return;
      }
      callSuccess(response);
    }

    @Override public void onFailure(okhttp3.Call call, IOException e) {
      try {
        callback.onFailure(OkHttpCall.this, e);
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }

    private void callFailure(Throwable e) {
      try {
        callback.onFailure(OkHttpCall.this, e);
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }

    private void callSuccess(Response<T> response) {
      try {
        callback.onResponse(OkHttpCall.this, response);
      } catch (Throwable t) {
        t.printStackTrace();
      }
    }
  });
}

总结:

OkHttpCall相对简单。

OkHttpCall是真实做网络请求的。根据传入的ServiceMethod和请求参数构建请求的Request,和真正执行请求的Okhttp的RealCall执行网络请求。